Skip to content

Instantly share code, notes, and snippets.

@jamiebuilds
Created February 14, 2014 05:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamiebuilds/8996178 to your computer and use it in GitHub Desktop.
Save jamiebuilds/8996178 to your computer and use it in GitHub Desktop.
Generated by SassMeister.com.
// ----
// Sass (v3.3.0.rc.3)
// Compass (v1.0.0.alpha.18)
// ----
@function str-split($string, $seperator) {
$result: ();
$temp: '';
@for $index from 1 through str-length($string) {
$char: str-slice($string, $index, $index);
@if $char != $seperator {
$temp: $temp + $char;
}
@else {
$result: append($result, $temp);
$temp: '';
}
}
$result: append($result, $temp);
@return $result;
}
@function str-is-number($string) {
@for $index from 1 through str-length($string) {
$char: str-slice($string, $index, $index);
@if not index('1' '2' '3' '4' '5' '6' '7' '8' '9' '0', $char) {
@return false;
}
}
@return true;
}
@function str-to-number($string) {
$result: 0;
@for $index from 1 through str-length($string) {
$char: str-slice($string, $index, $index);
$num: index('0' '1' '2' '3' '4' '5' '6' '7' '8' '9', $char) - 1;
$result: $result + $num;
@if $index < str-length($string) {
$result: $result * 10;
}
}
@return $result;
}
@function dot($map, $selection) {
$result: $map;
$selectors: str-split($selection, '.');
@each $selector in $selectors {
@if str-is-number($selector) {
$result: nth($result, str-to-number($selector) );
}
@else {
$result: map-get($result, $selector);
}
}
@return $result;
}
test {
$map: ( foo: (1, 2, 3, 4), bar: (5, 6, ( hi: (7, 8, 9) ), 10) );
test: dot($map, 'bar.3.hi.2');
}
@KittyGiraudel
Copy link

Great idea James, I really like the dot notation for accessors although I feel like your code is quite incomplete in some ways. But that's an amazing proof of concept.

Any use case for this yet?

@jamiebuilds
Copy link
Author

I was just hacking on this idea on the train on my way home after a night of drinking, I want to turn the function into a setter as well

$map: ( foo: (1, 2), bar: (3, 4) )

dot($map, "bar.1")
>> 3

dot($map, "bar.1", "setter")
// >> ( foo: (1, 2), bar: ("setter", 4) )

Which is just easier to read than (warning: semi-pseudo code):

$map: ( foo: (1, 2), bar: (3, 4) )

nth(map-get($map, "bar"), 1)
// >> 3

$val: map-get($map, "bar");
$result: ();
@for $index from 1 through length($val) {
  @if $index == 1 {
    $result: append($result, "setter");
  } @else {
    $result: append($result, nth($val, $index));
  }
}
map-merge($map, (bar: $result))
// >> ( foo: (1, 2), bar: ("setter", 4) )

This is going to make it a fairly complicated function, but I think it's possible.


Although, just thinking about it again, it may be better to do something like:

$map: ( foo: (1, 2), bar: (3, 4) )

get($map, "bar", 1)
// >> 3

set($map, "bar", 1, "setter")
// >> ( foo: (1, 2), bar: ("setter", 4) )
get( [map|list], [selection...] )
set( [map|list], [selection...], [setter] )

This would get rid of a big chunk of the parsing.


It could even be extended to something like:

run( [map|list], [selection...], [function-name]
@function square($n) {
  @return $n * $n;
}

$map: ( foo: (1, 2), bar: (3, 4) )

$map: run($map, 'bar', 1, 'square')
// >> ( foo: (1, 2), bar: (9, 4) )

Alas, I am ranting

@KittyGiraudel
Copy link

I'd like to see more on this. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment