question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

List assignment operator support

See original GitHub issue

Currently Sass supports appending to a list, but not setting an element to a list to a new value. The only way to implement this natively is to iterate through the list:

@function set-nth($list, $n, $value)
{
    $new_list: ();

    @for $i from 1 through max($n, length($list)) {
        @if ($i == $n) {
            $new_list: append($new_list, $value);
        } @else {
            @if (length($list) >= $i) {
                $new_list: append($new_list, nth($list, $i));
            } @else {
                $new_list: append($new_list, null);
            }
        }
    }

    @return $new_list;
}

This is exceptionally slow, and loading a 3rd party tool to add support for setting elements seems very silly.

set-nth should be introduced to the core, taking (list, n, value) and returning a new instance of the modified list.

This is related to #537, but this proposal retains the immutability of lists, creating a function which returns the modified list, in line with append.

Issue Analytics

  • State:open
  • Created 10 years ago
  • Comments:10

github_iconTop GitHub Comments

2reactions
KittyGiraudelcommented, Aug 10, 2013

I’ve made a couple of advanced lists functions too:

There is still a lot of room for improvements, starting with function names. I wasn’t sure how to call them.

/* ------------------------------------------------------------------------------- *
 * A couple of advanced Sass list functions
 * ------------------------------------------------------------------------------- *
 *
 * first($list)
 * Returns first element of $list
 *
 * last($list)
 * Returns last element of $list
 *
 * last-index($list, $value)
 * Returns last index of $value in $list
 *
 * to-string($list, $glue: '', $is-nested: false)
 * Joins all elements of $list with $glue
 *
 * prepend($list, $value)
 * Add $value as first index of $list
 *
 * insert-nth($list, $index, $value)
 * Add $value at $index in $list
 *
 * replace($list, $old-value, $new-value, $recursive: false)
 * Replace $old-value by $new-value in $list
 *
 * replace-nth($list, $index, $value)
 * Replace value at $index from $list by $value
 *
 * remove($list, $value, $recursive: false)
 * Remove value(s) $value from $list
 *
 * remove-nth($list, $index)
 * Remove value from $list at index $index
 *
 * slice($list, $start: 1, $end: length($list))
 * Slices $list between $start and $end
 *
 * reverse($list, $recursive: false)
 * Reverses the order of $list
 *
 * loop($list, $value: 1)
 * Shift indexes from $list of $value
 * 
 * ------------------------------------------------------------------------------- *
 * CodePen: http://codepen.io/HugoGiraudel/pen/loAgq
 * Repository: https://github.com/HugoGiraudel/Sass-snippets/blob/master/src/list-functions/
 * ------------------------------------------------------------------------------- */


/**
 * Returns first element of $list
 * -------------------------------------------------------------------------------
 * @example first(a, b, c) => a
 * -------------------------------------------------------------------------------
 * @param $list [List] : list
 * -------------------------------------------------------------------------------
 * @return [Literal]
 */
@function first($list) {
  @return nth($list, 1);
}

/**
 * Returns last element of $list
 * -------------------------------------------------------------------------------
 * @example last( (a, b, c) ) => c
 * -------------------------------------------------------------------------------
 * @param $list [List] : list
 * -------------------------------------------------------------------------------
 * @return [Literal]
 */
@function last($list) {
  @return nth($list, length($list));
}

/**
 * Returns last index of $value in $list
 * -------------------------------------------------------------------------------
 * @example last-index( (a, b, c), z )    => null
 * @example last-index( (a, b, c, a), a ) => 4
 * -------------------------------------------------------------------------------
 * @param $list [List] : list
 * @param $value [Literal] : value to be searched for
 * -------------------------------------------------------------------------------
 * @return [Number]
 */
@function last-index($list, $value) {
  @for $i from length($list)*-1 through -1 {
    @if nth($list, abs($i)) == $value {
      @return abs($i);
    }
  }

  @return null;
}

/**
 * Joins all elements of $list with $glue
 * -------------------------------------------------------------------------------
 * @example to-string( (a, b, c) )      => abc
 * @example to-string( (a, b, c), '-' ) => a-b-c
 * @example to-string( (a, b c, d) )    => abcd
 * -------------------------------------------------------------------------------
 * @param $list [List] : list
 * @param $glue [String] : value to use as a join string
 * @param $is-nested [Boolean] : strictly internal boolean for recursivity
 * -------------------------------------------------------------------------------
 * @return [String]
 */
@function to-string($list, $glue: '', $is-nested: false) {
  $result: null;

  @for $i from 1 through length($list) {
    $e: nth($list, $i);

    @if type-of($e) == list {
      $result: $result#{to-string($e, $glue, true)};
    }

    @else {
      $result: if($i != length($list) or $is-nested, $result#{$e}#{$glue}, $result#{$e});
    }
  }

  @return $result;
}

/**
 * Add $value as first index of $list
 * -------------------------------------------------------------------------------
 * @example prepend( (a, b, c), z )   => z, a, b, c
 * @example prepend( (a, b, c), y z ) => y z, a, b, c
 * -------------------------------------------------------------------------------
 * @param $list [List] : list
 * @param $value [Literal] : value to prepend to the list
 * -------------------------------------------------------------------------------
 * @return [List]
 */
@function prepend($list, $value) {
  @return join($value, $list);
}

/** 
 * Add $value at $index in $list
 * -------------------------------------------------------------------------------
 * @example insert-nth( (a, b, c),  2, z ) => a, z, b, c
 * @example insert-nth( (a, b, c),  0, z ) => error
 * @example insert-nth( (a, b, c), -1, z ) => error
 * @example insert-nth( (a, b, c), 10, z ) => error
 * -------------------------------------------------------------------------------
 * @param $list [List] : list
 * @param $index [Number] : index to add
 * @param $value [Literal] : value to add
 * -------------------------------------------------------------------------------
 * @raise [Error] if $index isn't an integer
 * @raise [Error] if $index is strictly lesser than 1
 * @raise [Error] if $index is strictly greater than length of $list
 * -------------------------------------------------------------------------------
 * @return [List]
 */
@function insert-nth($list, $index, $value) {
  $result: null;

  @if type-of($index) != number {
    @warn "$index: #{quote($index)} is not a number for `insert-nth`.";
  }

  @else if $index < 1 {
    @warn "List index 0 must be a non-zero integer for `insert-nth`";
  }

  @else if $index > length($list) {
    @warn "List index is #{$index} but list is only #{length($list)} item long for `insert-nth'.";
  }

  @else {
    $result: ();

    @for $i from 1 through length($list) {
      @if $i == $index {
        $result: append($result, $value);
      }

      $result: append($result, nth($list, $i));
    }
  }

  @return $result;
}

/**
 * Replace value at $index from $list by $value
 * -------------------------------------------------------------------------------
 * @example replace-nth( (a, b, c),   2, z ) => a, z, c
 * @example replace-nth( (a, b, c),   0, z ) => error
 * @example replace-nth( (a, b, c),  -1, z ) => a, b, z
 * @example replace-nth( (a, b, c),  10, z ) => error
 * @example replace-nth( (a, b, c), -10, z ) => error
 * -------------------------------------------------------------------------------
 * @param $list [List] : list
 * @param $index [Number] : index to update
 * @param $value [Literal] : new value for index $index
 * -------------------------------------------------------------------------------
 * @raise [Error] if $index isn't an integer
 * @raise [Error] if $index is 0
 * @raise [Error] if abs value of $index is strictly greater than length of $list
 * -------------------------------------------------------------------------------
 * @return [List]
 */
@function replace-nth($list, $index, $value) {
  $result: null;

  @if type-of($index) != number {
    @warn "$index: #{quote($index)} is not a number for `replace-nth`.";
  }

  @else if $index == 0 {
    @warn "List index 0 must be a non-zero integer for `replace-nth`.";
  }

  @else if abs($index) > length($list) {
    @warn "List index is #{$index} but list is only #{length($list)} item long for `replace-nth`.";
  }

  @else {
    $result: ();
    $index: if($index < 0, length($list) + $index + 1, $index);  

    @for $i from 1 through length($list) {
      @if $i == $index {
        $result: append($result, $value);
      }

      @else {
        $result: append($result, nth($list, $i));
      }
    }
  }

  @return $result;
}

/** 
 * Replace $old-value by $new-value in $list
 * -------------------------------------------------------------------------------
 * @example replace( (a, b, c), b, z )         => a, z, c
 * @example replace( (a, b, c), y, z )         => a, b, c
 * @example replace( (a, b, c a), a, z )       => z, b, c z
 * @example replace( (a, b, c a), a, z, true ) => z, b, c z
 * -------------------------------------------------------------------------------
 * @param $list [List] : list
 * @param $old-value [Literal] : value to replace
 * @param $new-value [Literal] : new value for $old-value
 * @param $recursive [Boolean] : enable / disable recursivity
 * -------------------------------------------------------------------------------
 * @return [List]
 */
@function replace($list, $old-value, $new-value, $recursive: false) {
  $result: ();

  @for $i from 1 through length($list) {
    @if type-of(nth($list, $i)) == list and $recursive {
      $result: append($result, replace(nth($list, $i), $old-value, $new-value, $recursive));
    }

    @else {
      @if nth($list, $i) == $old-value {
        $result: append($result, $new-value);
      }

      @else {
        $result: append($result, nth($list, $i));
      }
    }
  }

  @return $result;
}

/**
 * Remove value from $list at index $index
 * -------------------------------------------------------------------------------
 * @example remove-nth( (a, b, c),   2 ) => a, c
 * @example remove-nth( (a, b, c),   0 ) => error
 * @example remove-nth( (a, b, c),  -1 ) => a, b
 * @example remove-nth( (a, b, c),  10 ) => error
 * @example remove-nth( (a, b, c), -10 ) => error
 * -------------------------------------------------------------------------------
 * @param $list [List] : list
 * @param $index [Number] : index to remove
 * -------------------------------------------------------------------------------
 * @raise [Error] if $index isn't an integer
 * @raise [Error] if $index is 0
 * @raise [Error] if abs value of $index is strictly greater then length of $list
 * -------------------------------------------------------------------------------
 * @return [List]
 */
@function remove-nth($list, $index) {
  $result: null;

  @if type-of($index) != number {
    @warn "$index: #{quote($index)} is not a number for `remove-nth`.";
  }

  @else if $index == 0 {
    @warn "List index 0 must be a non-zero integer for `remove-nth`.";
  }

  @else if abs($index) > length($list) {
    @warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`.";
  }

  @else {
    $result: ();
    $index: if($index < 0, length($list) + $index + 1, $index);  

    @for $i from 1 through length($list) {
      @if $i != $index {
        $result: append($result, nth($list, $i));
      }
    }
  }

  @return $result;
}

/**
 * Remove value(s) $value from $list
 * -------------------------------------------------------------------------------
 * @example remove( (a, b, c),   b )       => a, c
 * @example remove( (a, b, c),   z )       => a, b, c
 * @example remove( (a, b, c b), b )       => a, c b
 * @example remove( (a, b, c b), b, true ) => a, c
 * -------------------------------------------------------------------------------
 * @param $list [List] : list
 * @param $value [Literal] : value to remove
 * @param $recursive [Boolean] : enable / disable recursivity
 * -------------------------------------------------------------------------------
 * @return [List]
 */
@function remove($list, $value, $recursive: false) {
  $result: ();

  @for $i from 1 through length($list) {
    @if type-of(nth($list, $i)) == list and $recursive {
      $result: append($result, remove(nth($list, $i), $value, $recursive));
    }

    @else if nth($list, $i) != $value {
      $result: append($result, nth($list, $i));
    }
  }

  @return $result;
}

/**
 * Slices $list between $start and $end
 * -------------------------------------------------------------------------------
 * @example slice( (a, b, c, d),  2, 3 ) => b, c
 * @example slice( (a, b, c, d),  3, 2 ) => error
 * @example slice( (a, b, c, d),  3, 5 ) => error
 * @example slice( (a, b, c, d), -1, 3 ) => error
 * @example slice( (a, b, c, d),  0, 3 ) => error
 * @example slice( (a, b, c, d),  3, 3 ) => c
 * -------------------------------------------------------------------------------
 * @param $list [List] : list
 * @param $start [Number] : start index
 * @param $end [Number] : end index
 * -------------------------------------------------------------------------------
 * @raise [Error] if $start or $end aren't integers
 * @raise [Error] if $start is greater than $end
 * @raise [Error] if $start or $end is strictly lesser than 1
 * @raise [Error] if $start is strictly greater than length of $list
 * @raise [Error] if $end is strictly greater than length of $list
 * -------------------------------------------------------------------------------
 * @return [List]
 */ 
@function slice($list, $start: 1, $end: length($list)) {
  $result: null;

  @if type-of($start) != number or type-of($end) != number {
    @warn "Either $start or $end are not a number for `slice`.";
  }

  @else if $start > $end {
    @warn "The start index has to be lesser than or equals to the end index for `slice`.";
  }

  @else if $start < 1 or $end < 1 {
    @warn "List indexes must be non-zero integers for `slice`.";
  }

  @else if $start > length($list) {
    @warn "List index is #{$start} but list is only #{length($list)} item long for `slice`.";
  }

  @else if $end > length($list) {
    @warn "List index is #{$end} but list is only #{length($list)} item long for `slice`.";
  }

  @else {
    $result: ();

    @for $i from $start through $end {
      $result: append($result, nth($list, $i));
    }
  }

  @return $result;
}

/**
 * Reverses the order of $list
 * -------------------------------------------------------------------------------
 * @example reverse( (a, b, c) )         => c, b, a
 * @example reverse( (a, b, c a) )       => c a, b, a
 * @example reverse( (a, b, c a), true ) => a c, b, a
 * @example reverse( a )                 => a
 * -------------------------------------------------------------------------------
 * @param $list [List] : list
 * @param $recursive [Boolean] : enable / disable recursivity
 * -------------------------------------------------------------------------------
 * @return [List]
 */
@function reverse($list, $recursive: false) {
   $result: ();

   @for $i from length($list)*-1 through -1 {
      @if type-of(nth($list, abs($i))) == list and $recursive {
        $result: append($result, reverse(nth($list, abs($i)), $recursive));      
      }

      @else {
        $result: append($result, nth($list, abs($i)));
      }
   }

   @return $result;
}

/**
 * Shift indexes from $list of $value
 * -------------------------------------------------------------------------------
 * @example loop( (a, b, c, d, e) )     => e, a, b, c, d
 * @example loop( (a, b, c, d, e),  2 ) => d, e, a, b, c
 * @example loop( (a, b, c, d, e), -2 ) => c, d, e, a, b
 * -------------------------------------------------------------------------------
 * @param $list [List] : list
 * @param $value [Number] : number of position between old and new indexes
 * -------------------------------------------------------------------------------
 * @return [List]
 */
@function loop($list, $value: 1) {
  $result: ();

  @for $i from 0 to length($list) {
    $result: append($result, nth($list, ($i - $value) % length($list) + 1));
  }

  @return $result;
}
1reaction
chriseppsteincommented, Aug 27, 2014

Agree. List helpers are super important.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Assignment Operators in Python - GeeksforGeeks
Here, we will cover Assignment Operators in Python. So, Assignment Operators are used to assigning values to variables.
Read more >
Assignment operators - cppreference.com
Concurrency support library (C++11) ... List initialization (C++11) ... Assignment operators modify the value of the object.
Read more >
Python Operators - A Quick Reference | DigitalOcean
List of Python Operators · Assignment Operators · Arithmetic Operators · Logical Operators · Comparison Operators · Bitwise Operators ...
Read more >
Python Assignment Operators - W3Schools
Operator Example Same As Try it = x = 5 x = 5 Try it » += x += 3 x = x + 3...
Read more >
Assignment Operators in C - Tutorialspoint
Assignment Operators in C, The following table lists the assignment operators supported by the C language −
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found