I have created the following list:

  List files = <List>[
    ["File1.jpg", "Name 1"],
    ["File2.jpg", "Name 2"],
    ["File3.jpg", "Name 3"],
  ];

The idea behind this list is to access to some files showed on a ListView and display some titles instead of the name of the files.

Is there any way to access the elements by column?

As mentioned in this post, I can access to individual elements as:

 files[0][0] = "File1.jpg";

But would like to get the following from the list above:

["File1.jpg", "File2.jpg", "File3.jpg"] // and
["Name 1", "Name 2", "Name 3"] 

with something like: files[all rows][0] and files[all rows][1]

I need this or something similar because I have implemented a search bar by name, so when I search "2" I could get ["File2.jpg", "Name 2"].


Solution 1: Richard Heap

You can pre-process the list to give you the columns like this:

  var files = <List>[
    ['File1.jpg', 'Name 1'],
    ['File2.jpg', 'Name 2'],
    ['File3.jpg', 'Name 3'],
  ];

  var col0 = files.map<String>((row) => row[0]).toList(growable: false);
  var col1 = files.map<String>((row) => row[1]).toList(growable: false);

col0 and col1 are now List<String> with the values by column.

Consider using where to select the particular matching (you get to define what "matching" means) rows. For example:

  var criterion = '2';
  var selected = files.where((row) {
    for (var col in row) {
      if (col.contains(criterion)) {
        return true;
      }
    }
    return false;
  }).toList();
  print (selected);


Solution 2: mezoni

Below are some ways to find values in your array.

void main() {
  final result1 = search1(files, '2');
  print(result1);
  final result2 = search1(files, '2');
  print(result2);
  final result3 = search3(files, [0, 1], '2');
  print(result3);
}

Iterable<Iterable<String>> search1(List<List<String>> source, String word) {
  return source.where((e) => e.any((e) => e.contains(word)));
}

Iterable<Iterable<String>> search2(List<List<String>> source, String word) {
  return source.where((e) => e[0].contains(word) || e[1].contains(word));
}

Iterable<Iterable<String>> search3(
    List<List<String>> source, List<int> columns, String word) {
  return source.where((e) => columns.any((c) => e[c].contains(word)));
}

final files = [
  ['File1.jpg', 'Name 1'],
  ['File2.jpg', 'Name 2'],
  ['File3.jpg', 'Name 3'],
];

Result:

([File2.jpg, Name 2])
([File2.jpg, Name 2])
([File2.jpg, Name 2])