Sort 2D list in flutter depending on 3rd element of each list

Viewed 252

I am trying to sort a 2D list depending on user requirement like [i][1] or [i][2]. To achieve this I first convert the list to a map and then add a map to the list then sort list containing map and then again convert it to a 2D list (I know sounds a bit stupid but this was the best solution I found). Code -

{
    List a = [];
    List a1 = [];
//Convert 2D list to list Map
    for (int i = 0; i < itemData.length; i++) {
      Map<String, dynamic> b = {
        "0": itemData[i][0],
        "1": itemData[i][1],
        "2": itemData[i][2],
        "3": itemData[i][3],
        "4": itemData[i][4],
        "5": itemData[i][5],
        "6": itemData[i][6],
        "7": itemData[i][7],
        "8": itemData[i][8],
      };
      a.add(b);
    }
// sorting list map
    a.sort((m1, m2) {
      var r = m1[x].compareTo(m2[x]);
      return r;
    });
// reconverting list map to 2D list
    for (int i = 0; i < a.length; i++) {
      a1.add(a[i].entries.map((e) => e.value).toList());
    }
  }

The code works fine for 6 elements but not sure why it's not working for more elements. when I am printing a after creating a map and adding to the list its printing only 6 elements. I don't know what's going wrong why it's failing to add all elements, if there is a better way i can do this or whats wrong i am doing in it.

Eg

[[18,1,2.3,true],[18,10,8.5,true],[18,2,6.5,false],[24,5,7.6,true],[12,2,3.4,false]]

sorting it depending on [i][2] (third element of each list)

[[18,1,2.3,true],[12,2,3.4,false],[18,2,6.5,false],[24,5,7.6,true],[18,10,8.5,true]]
3 Answers
var l = [
  [18,1,2.3,true],
  [18,10,8.5,true],
  [18,2,6.5,false],
  [24,5,7.6,true],
  [12,2,3.4,false]
];

int comparisonIndex = 2;

List<List<dynamic>> s = l
  ..sort((x, y) => (x[comparisonIndex] as dynamic)
    .compareTo((y[comparisonIndex] as dynamic)));

print(s); // [[18, 1, 2.3, true], [12, 2, 3.4, false], [18, 2, 6.5, false], [24, 5, 7.6, true], [18, 10, 8.5, true]]

In the case of bool compareTo would not work as the type does not implement Comparable, here I have returned 0 in the case of true and 1 in the case of false

int comparisonIndex = 3;

dynamic getValue(dynamic v) {
  if (v.runtimeType == bool) {
    if (v as bool) {
      return 0;
    }
    return 1;
  }
  return v;
}

List<List<dynamic>> s = l
   ..sort((x, y) => getValue(x[comparisonIndex])
      .compareTo(getValue(y[comparisonIndex])));
print(s); // [[18, 1, 2.3, true], [18, 10, 8.5, true], [24, 5, 7.6, true], [18, 2, 6.5, false], [12, 2, 3.4, false]]

Hard coding is usually not a good idea. Maybe try like this?

List<List<int>> list2D = [
  [4, 2, 3],
  [4, 2, 1, 3, 5]
];
List<List<int>> sorted = [];

for (var i = 0; i < list2D.length; i++) {
  sorted.add(
    list2D[i]
      ..sort((a, b) {
        return a.compareTo(b);
      }),
  );
}

Another solution based on comment below:

final original = [
  [18, 1, 2.3, true],
  [18, 10, 8.5, true],
  [18, 2, 6.5, false],
  [24, 5, 7.6, true],
  [12, 2, 3.4, false]
];
original.sort((a, b) => (a[2] as double).compareTo(b[2] as double));
print(original);

Try this:

void main() {
   List<List<dynamic>> list=  [[18,1,2.3,true],[18,10,8.5,true],[18,2,6.5,false],[24,5,7.6,true],[12,2,3.4,false]];

   List<List<dynamic>> sortedList = list..sort((a,b)=>(a[2] as double).compareTo((b[2] as double)));
  
  print(sortedList);
}
Related