Lists and Maps Data Structures

1. List Creation and Manipulation Functions

List Type Syntax Example Notes
Space-separated value1 value2 value3 $list: 10px 20px 30px; Most common, like CSS values
Comma-separated value1, value2, value3 $list: red, green, blue; Explicit list structure
Single Item (value,) $single: (item,); Trailing comma makes it a list
Empty List () $empty: (); Zero-length list
Parenthesized (val1, val2) $list: (a, b, c); Explicit grouping
Nested List list within list $nested: (1 2) (3 4); Multi-dimensional data
Index 1-based (not 0-based) First item is index 1 Different from JavaScript

Example: List creation patterns

// Space-separated (like margin values)
$margins: 10px 20px 10px 20px;

// Comma-separated (like font stack)
$fonts: Arial, Helvetica, sans-serif;

// Explicit parentheses
$sizes: (small, medium, large);

// Single-item list (needs trailing comma)
$single: (blue,);

// Empty list
$empty: ();

// Nested lists (matrix-like)
$grid: (1 2 3) (4 5 6) (7 8 9);

// Mixed separators (outer: space, inner: comma)
$complex: (a, b) (c, d) (e, f);

// List in variable
$colors: red blue green;
$first: nth($colors, 1);  // red
$length: length($colors);  // 3

2. List Functions (nth, length, append, join, index)

Function Syntax Description Example
nth() nth($list, $n) Get item at index n (1-based) nth((a, b, c), 2) → b
length() length($list) Count of items in list length((a, b, c)) → 3
append() append($list, $val, $sep) Add item to end of list append((a, b), c) → a, b, c
join() join($list1, $list2, $sep) Combine two lists join((a, b), (c, d)) → a, b, c, d
index() index($list, $value) Find position of value (or null) index((a, b, c), b) → 2
list-separator() list-separator($list) Get separator type space | comma
set-nth() set-nth($list, $n, $val) Replace item at index set-nth((a, b, c), 2, x) → a, x, c
zip() zip($lists...) Combine multiple lists into nested zip((a, b), (1, 2)) → (a 1), (b 2)
is-bracketed() is-bracketed($list) Check if list uses [] is-bracketed([a, b]) → true

Example: List function usage

$colors: red, green, blue, yellow;

// nth - Get item by index (1-based)
$first: nth($colors, 1);        // red
$last: nth($colors, -1);        // yellow (negative index)

// length - Count items
$count: length($colors);         // 4

// append - Add to end
$extended: append($colors, purple);
// → red, green, blue, yellow, purple

// append with separator
$spaced: append((a b), c, space);  // a b c
$comma: append((a b), c, comma);   // a, b, c

// join - Combine lists
$list1: (a, b);
$list2: (c, d);
$joined: join($list1, $list2);   // a, b, c, d

// index - Find position
$pos: index($colors, blue);      // 3
$not-found: index($colors, pink); // null

// set-nth - Replace item
$modified: set-nth($colors, 2, orange);
// → red, orange, blue, yellow

// zip - Combine into pairs
$names: (a, b, c);
$nums: (1, 2, 3);
$pairs: zip($names, $nums);
// → (a 1), (b 2), (c 3)

// Practical: Generate classes
$sizes: small, medium, large;
@each $size in $sizes {
  .text-#{$size} {
    font-size: nth((12px, 16px, 20px), index($sizes, $size));
  }
}
Warning: List indices are 1-based, not 0-based. nth($list, 1) gets the first item.

3. Map Creation and Key-Value Operations

Concept Syntax Example Notes
Map Syntax (key: value, key2: value2) $map: (primary: blue, secondary: green); Parentheses required
Key Types Any data type Strings, numbers, colors, etc. Usually strings or numbers
Value Types Any data type Including nested maps/lists Can be complex structures
Empty Map () $empty: (); Same as empty list
Quoted Keys ("key": value) Optional for most keys Required for special chars
Trailing Comma Allowed (a: 1, b: 2,) Optional but useful for git diffs

Example: Map creation and structure

// Basic map
$colors: (
  primary: #3498db,
  secondary: #2ecc71,
  danger: #e74c3c
);

// Nested map (theme system)
$theme: (
  colors: (
    text: #333,
    bg: #fff,
    accent: blue
  ),
  spacing: (
    small: 8px,
    medium: 16px,
    large: 24px
  ),
  fonts: (
    heading: 'Georgia',
    body: 'Arial'
  )
);

// Numeric keys
$breakpoints: (
  320: 'mobile',
  768: 'tablet',
  1024: 'desktop'
);

// Mixed value types
$config: (
  enabled: true,
  count: 5,
  color: red,
  sizes: (10px, 20px, 30px),
  nested: (
    deep: value
  )
);

// Empty map
$empty: ();

// Single entry (still needs parentheses)
$single: (key: value);

4. Map Functions (get, set, merge, remove, keys, values)

Function Syntax Description Example
map-get() map-get($map, $key) Retrieve value by key map-get((a: 1), a) → 1
map-has-key() map-has-key($map, $key) Check if key exists map-has-key((a: 1), a) → true
map-keys() map-keys($map) Get list of all keys map-keys((a: 1, b: 2)) → a, b
map-values() map-values($map) Get list of all values map-values((a: 1, b: 2)) → 1, 2
map-merge() map-merge($map1, $map2) Combine maps (shallow) map-merge((a: 1), (b: 2)) → (a: 1, b: 2)
map-remove() map-remove($map, $keys...) Remove keys from map map-remove((a: 1, b: 2), a) → (b: 2)
Deep Get NEW map.get($map, $keys...) Get nested value Use sass:map module
Deep Merge NEW map.deep-merge($map1, $map2) Recursive merge Modern module function

Example: Map function operations

$colors: (
  primary: #3498db,
  secondary: #2ecc71,
  danger: #e74c3c,
  warning: #f39c12
);

// map-get - Retrieve value
$primary: map-get($colors, primary);  // #3498db

// map-has-key - Check existence
@if map-has-key($colors, primary) {
  .btn { background: map-get($colors, primary); }
}

// map-keys - Get all keys
$color-names: map-keys($colors);
// → primary, secondary, danger, warning

// map-values - Get all values
$color-values: map-values($colors);
// → #3498db, #2ecc71, #e74c3c, #f39c12

// map-merge - Combine maps
$new-colors: (success: green, info: blue);
$all-colors: map-merge($colors, $new-colors);
// Adds success and info to existing colors

// map-remove - Delete keys
$subset: map-remove($colors, danger, warning);
// → (primary: #3498db, secondary: #2ecc71)

// ===================================
// Practical: Generate utility classes
@each $name, $color in $colors {
  .bg-#{$name} {
    background: $color;
  }
  .text-#{$name} {
    color: $color;
  }
}

// ===================================
// Modern sass:map module
@use 'sass:map';

$theme: (
  colors: (
    primary: (
      base: blue,
      light: lightblue
    )
  )
);

// Deep get (nested access)
$base-color: map.get($theme, 'colors', 'primary', 'base');
// → blue

// Deep merge
$theme2: (
  colors: (
    primary: (
      dark: darkblue
    )
  )
);
$merged: map.deep-merge($theme, $theme2);
// Recursively merges nested maps
Note: Use modern @use 'sass:map'; module for advanced operations like map.deep-merge() and map.deep-remove().

5. Multi-dimensional Lists and Nested Maps

Structure Syntax Access Pattern Use Case
2D List (Matrix) ((a, b), (c, d)) nth(nth($matrix, row), col) Grid layouts, tables
List of Lists (list1) (list2) (list3) Iterate outer then inner Grouped configurations
Nested Maps (key: (nested-key: val)) Multiple map-get calls Theme systems, config
Map of Lists (key: (val1, val2)) map-get then nth Multiple values per key
List of Maps ((k: v), (k: v)) nth then map-get Array of objects pattern
Deep Nesting 3+ levels Chain access functions Complex data structures

Example: Multi-dimensional data structures

// 2D List (Matrix)
$grid: (
  (1, 2, 3),
  (4, 5, 6),
  (7, 8, 9)
);

// Access: row 2, column 3
$row: nth($grid, 2);        // (4, 5, 6)
$value: nth($row, 3);       // 6

// Nested Maps (Theme System)
$theme: (
  colors: (
    primary: (
      base: #3498db,
      light: #5dade2,
      dark: #2874a6
    ),
    secondary: (
      base: #2ecc71,
      light: #58d68d,
      dark: #229954
    )
  ),
  spacing: (
    small: 8px,
    medium: 16px,
    large: 24px
  )
);

// Deep access
$colors: map-get($theme, colors);
$primary: map-get($colors, primary);
$base: map-get($primary, base);  // #3498db

// Map of Lists (Breakpoint ranges)
$breakpoints: (
  mobile: (320px, 767px),
  tablet: (768px, 1023px),
  desktop: (1024px, 1439px),
  wide: (1440px, null)
);

$tablet-range: map-get($breakpoints, tablet);
$min: nth($tablet-range, 1);  // 768px
$max: nth($tablet-range, 2);  // 1023px

// List of Maps (Menu items)
$menu: (
  (label: 'Home', url: '/', icon: 'house'),
  (label: 'About', url: '/about', icon: 'info'),
  (label: 'Contact', url: '/contact', icon: 'mail')
);

@each $item in $menu {
  $label: map-get($item, label);
  $url: map-get($item, url);
  
  .nav-#{to-lower-case($label)} {
    content: $label;
  }
}

// ===================================
// Helper function for deep access
@function deep-get($map, $keys...) {
  @each $key in $keys {
    $map: map-get($map, $key);
  }
  @return $map;
}

// Usage
$color: deep-get($theme, colors, primary, base);
// → #3498db

Example: Map Pattern

$config: (
  colors: (
    brand: #333
  ),
  sizes: (
    base: 16px
  )
);

// Access
$brand: map-get(
  map-get($config, colors),
  brand
);

Example: List of Maps Pattern

$items: (
  (name: a, val: 1),
  (name: b, val: 2),
  (name: c, val: 3)
);

// Iterate
@each $item in $items {
  $n: map-get($item, name);
  $v: map-get($item, val);
}

6. List and Map Iteration Patterns

Pattern Syntax Variables Use Case
Each List Item @each $item in $list $item: current value Simple iteration
Each with Index @for $i from 1 through length($list) $i: index, use nth($list, $i) Need position number
Each Map Entry @each $key, $value in $map $key, $value: pair Map iteration
Nested List @each $item in $list { @each $sub in $item } Nested loop variables Multi-dimensional data
Destructuring @each $a, $b in $list Unpack list items Paired values
Map Keys Only @each $key in map-keys($map) $key: key only Key-based operations
Map Values Only @each $val in map-values($map) $val: value only Value-based operations

Example: Iteration patterns

// Simple list iteration
$sizes: small, medium, large;

@each $size in $sizes {
  .text-#{$size} {
    font-size: $size;
  }
}

// List with index
$colors: red, green, blue;

@for $i from 1 through length($colors) {
  .color-#{$i} {
    color: nth($colors, $i);
    z-index: $i;
  }
}

// Map iteration (key-value)
$breakpoints: (
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px
);

@each $name, $width in $breakpoints {
  @media (min-width: $width) {
    .container-#{$name} {
      max-width: $width;
    }
  }
}

// Nested list iteration
$grid: (
  (1, 2, 3),
  (4, 5, 6),
  (7, 8, 9)
);

@each $row in $grid {
  @each $cell in $row {
    .cell-#{$cell} {
      order: $cell;
    }
  }
}

// List destructuring (paired values)
$pairs: (10px 1), (20px 2), (30px 3);

@each $size, $weight in $pairs {
  .combo-#{$weight} {
    font-size: $size;
    font-weight: $weight * 100;
  }
}

// Map keys iteration
@each $name in map-keys($breakpoints) {
  .visible-#{$name} {
    display: none;
    
    @media (min-width: map-get($breakpoints, $name)) {
      display: block;
    }
  }
}

// Complex: List of maps
$buttons: (
  (variant: primary, color: blue, text: white),
  (variant: secondary, color: gray, text: black),
  (variant: danger, color: red, text: white)
);

@each $btn in $buttons {
  .btn-#{map-get($btn, variant)} {
    background: map-get($btn, color);
    color: map-get($btn, text);
  }
}

// Practical: Generate utility classes
$spacings: (
  0: 0,
  1: 0.25rem,
  2: 0.5rem,
  3: 1rem,
  4: 1.5rem,
  5: 3rem
);

$sides: (
  t: top,
  r: right,
  b: bottom,
  l: left
);

@each $size-key, $size-val in $spacings {
  @each $side-key, $side-val in $sides {
    .m#{$side-key}-#{$size-key} {
      margin-#{$side-val}: $size-val;
    }
    .p#{$side-key}-#{$size-key} {
      padding-#{$side-val}: $size-val;
    }
  }
}
// Generates: mt-0, mt-1, mr-0, mr-1, pt-0, etc.

Iteration Best Practices

  • Use @each for lists when index is not needed
  • Use @each $key, $value for maps to get both
  • Use @for when you need the index/counter
  • Destructure lists when items are paired values
  • Combine map-keys() or map-values() with @each when only one is needed
  • Keep nested iterations shallow (max 2-3 levels) for readability
Note: Lists and maps are immutable. Functions like append() and map-merge() return new structures without modifying originals.