Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I'm trying to build a sortable grid:

sortBy[data_, idx_] := 
  If[idx == 0, data, Sort[data, #1[[idx]] < #2[[idx]] &]];
sortableTable[data_, header_] := DynamicModule[
  {h, sort = 0},
  h = MapIndexed[Button[#1, sort = #2] &, header];
  Dynamic[Grid[Prepend[sortBy[data, sort], h]]]];
sortableTable[
  Table[
    RandomInteger[100], {i, 3}, {j, 4}], 
    {"First", "Second", "Third", "Fourth"}]

For some reason it is not behaving like I expected: header disappears and sorting doesn't occur. I've tried all sorts of stuff but can't make it work like intended. Any help is much appreciated.

share|improve this question
3  
try: sort = First@#2 in the MapIndexed –  Pinguin Dirk Sep 9 '13 at 17:54
    
Thanks. This was the actual error. –  mikea Sep 9 '13 at 20:24

3 Answers 3

up vote 6 down vote accepted

This should work:

rows = 3;
cols = 4;
data = RandomInteger[{1, 100}, {rows, cols}];
names = {"First", "Second", "Third", "Fourth"};
sortBy[data_, idx_] := If[idx == 0, data, Sort[data, #1[[idx]] < #2[[idx]] &]];
Dynamic@Grid@Prepend[data, Array[Button[names[[#]], data = sortBy[data, #]] &, cols]]

enter image description here

share|improve this answer

There is no need to re-invent SortBy.

Stealing ybeltukov solution:

Dynamic@Grid@
 Prepend[data, 
         Array[Button[names[[#]],
                      data = SortBy[data, Function[x, #[[x]] &][#]]
                     ] &
               , cols]
        ]
share|improve this answer
    
You forgot to localize x. –  Mr.Wizard Sep 9 '13 at 21:14
    
@Mr.Wizard I didn't, I was just too lazy to do this. Or frustrated by recent question where no one cared about localiziing t or letter case in sin till you posted the answer :) –  Kuba Sep 9 '13 at 21:18
1  
@Mr.Wizard But I should act like an adult so I've edited it :p –  Kuba Sep 9 '13 at 21:32

Here is a possibility:

SeedRandom[1];
labels = {"First", "Second", "Third", "Fourth"};
nrows = 4;
data = RandomInteger[{1, 100}, {nrows, Length@labels}];

DynamicModule[{idx = 1},
 Dynamic@Grid[
   Prepend[SortBy[data, #[[idx]] &], 
    MapIndexed[Setter[Dynamic@idx, #2, #1] &, labels]],
   Spacings -> {0, Automatic}]
 ]

Mathematica graphics

If speed on a large dataset should happen to be an issue (unlikely, since the data are displayed), then this will be faster:

DynamicModule[{idx = 1},
 Dynamic@Grid[
   Prepend[data[[Ordering[data[[All, idx]]]]], 
    MapIndexed[Setter[Dynamic@idx, #2, #1] &, labels]],
   Spacings -> {0, Automatic}]
 ]
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.