Quentin
Quentin

Reputation: 516

How to sort List<File> in Dart with null objects at end

Starting to take in hand Flutter for a study project, I'm wondering about sorting a list of files.

Indeed, my program has a list of 4 files initialized like this :

List<File> imageFiles = List(4);

This initialization actually implies that my list is like this : [null,null,null,null].

When the user performs actions, this list can fill up. However, the user can delete a file at any time, which can give us the following situation: [file A, null, null, file d].

My question is, how to sort the list when a deletion arrives in order to have a list where null objects are always last ([file A, file D, null, null]).

I've looked at a lot of topics already, but they never concern the DART.

Thank you in advance for your help.

Upvotes: 5

Views: 4986

Answers (3)

You can try this: Demo (Dartpad)

This place all null at end.

sortedList.sort((a, b) {
  int result;
  if (a == null) {
    result = 1;
  } else if (b == null) {
    result = -1;
  } else {
    // Ascending Order
    result = a.compareTo(b);
  }
  return result;
})

You can play with this another demo too: Demo 2 - Dartpad

Upvotes: 8

Donny Rozendal
Donny Rozendal

Reputation: 1054

For anyone interested, I made an extension function of Jorge's answer.

extension ListExtension<E> on List<E> {
  void sortByNullable<K extends Comparable<K>>(K? Function(E element) keyOf) {
    sortByCompare((element) => keyOf(element), (a, b) {
      if (a == null) {
        return 1;
      } else if (b == null) {
        return -1;
      } else {
        return a.compareTo(b);
      }
    });
  }
}

Upvotes: 1

dumazy
dumazy

Reputation: 14445

You can sort the list with list.sort((a, b) => a == null ? 1 : 0);

Here's a full example, with String instead of File, that you can run on DartPad

void main() {
  List<String> list = List(4);
  list[0] = "file1";
  list[3] = "file4";

  print("list before sort: $list"); 
  // list before sort: [file1, null, null, file4]

  list.sort((a, b) => a == null ? 1 : 0);

  print("list after sort: $list"); 
  // list after sort: [file1, file4, null, null]

}

If it's a business requirement to have a max of 4 files, I would suggest creating a value object that can handle with that. For example:

class ImageList {
  final _images = List<String>();

  void add(String image) {
    if(_images.length < 4) {
      _images.add(image);
    }
  }

  void removeAt(int index) {
    _images.removeAt(index);
  }

  String get(int index) {
    return _images[index];
  }

  List getAll() {
    return _images;
  }
}

And you could run it like this:

void main() {
  ImageList imageList = ImageList();
  imageList.add("file1");
  imageList.add("file2");
  imageList.add("file3");
  imageList.add("file4");
  imageList.add("file5"); // won't be add

  print("imagelist: ${imageList.getAll()}");
  // imagelist: [file1, file2, file3, file4]

  imageList.removeAt(2); // remove file3
  print("imagelist: ${imageList.getAll()}");
  // imagelist: [file1, file2, file4]
}

This will make it easier to have control. (This example was again with String instead of File)

Upvotes: 10

Related Questions