1// List sorting via a modified merge-sort algorythmn
2// http://en.wikipedia.org/wiki/Merge_sort
3
4@function ms-merge($A, $B) {
5
6  $Return: ();
7
8  // Some empty lists get passed through
9  // so just pass the other list throguh
10  @if length($A) == 0 {
11    @return $B;
12  }
13
14  // If lists fit next to each other, just merge them
15  // This helps performance skipping the need to check each value
16  @if nth($A, length($A)) < nth($B, 1) {
17    @return join($A, $B);
18  }
19  @if nth($B, length($B)) < nth($A, 1) {
20    @return join($B, $A);
21  }
22
23  // Counters start at 1
24  $A-counter: 1;
25  $B-counter: 1;
26
27  // Start looping through all numbers in array
28  @while $A-counter <= length($A) and $B-counter <= length($B) {
29
30    // Check if the A value is smaller
31    // Uses or equal to avoid duplicate numbers
32    @if nth($A, $A-counter) <= nth($B, $B-counter) {
33      $Return: join($Return, nth($A, $A-counter));
34      $A-counter: $A-counter + 1;
35    }
36
37    // Check if the B value is smaller
38    @elseif nth($A, $A-counter) > nth($B, $B-counter) {
39      $Return: join($Return, nth($B, $B-counter));
40      $B-counter: $B-counter + 1;
41    }
42  }
43
44  // Run through remainder values in the list
45  @while $A-counter <= length($A) {
46    $Current: nth($A, $A-counter);
47    @if $Current != nth($Return, length($Return)) {
48      $Return: join($Return, $Current);
49    }
50    $A-counter: $A-counter + 1;
51  }
52  @while $B-counter <= length($B) {
53    $Current: nth($B, $B-counter);
54    @if $Current != nth($Return, length($Return)) {
55      $Return: join($Return, $Current);
56    }
57    $B-counter: $B-counter + 1;
58  }
59
60  // Done! return is now sorted and complete
61  @return $Return;
62}
63
64
65
66// Pull it all together
67@function ms-sort-list($Lists) {
68
69  $Return: ();
70
71  @each $List in $Lists {
72    @if $Return == () {
73      $Return: $List;
74    }
75    @else {
76      $Return: ms-merge($List, $Return);
77    }
78  }
79
80  // final cleanup of repeated items
81  $Last: null;
82  $New-list: ();
83  @each $Item in $Return {
84    @if $Item != $Last {
85      $New-list: join($New-list, $Item);
86    }
87    $Last: $Item;
88  }
89  $Return: $New-list;
90
91
92  @return $Return;
93}