How can I order objects by price in Dart? - dart

I have tried to sort the list of objects based on the price of each individual object has. However, I have got this error the expression here has a type of void, and therefore it cannot be used
class Item{
String productName;
double price;
}
List<Item> items = ...;
items.sort((a, b) => a.price.compareTo(b.price));

List.sort modifies the object on which it is call. It doesn't return any value and you have to use the original list.
var list = [3, 1, 2];
list.sort();
print(list); // displays [1, 2, 3]
If you want to inline the .sort() to use the list directly, you can use the cascade notation:
var list = [3, 1, 2]..sort();
print(list); // displays [1, 2, 3]
// or
var list = [3, 1, 2];
print(list..sort()); // displays [1, 2, 3]

Related

Is it possible to remove duplicates in Dart with another variable

I have searched a lot for removing duplicates from a list in Dart using ANOTHER variable.
Here is what I mean:
List<int> numbers = [1, 2, 3, 4];
// This list has 4 new elements than the first one
List<int> moreNumbers = [1, 2, 3, 4, 5, 6, 7, 8];
// Now I want to push the moreNumbers unique elements to the numbers one
I want to push it so the end result for the numbers variable should be:
[1, 2, 3, 4, 5, 6, 7, 8];
Is it possible?
void main() {
var lst = [1,2,3,4];
var lst2 = [1,2,3,4,5,6,7,8];
var s = {...(lst+lst2)};
print(s.toList());
}
The trivial approach would be:
for (var number in moreNumbers) {
if (!numbers.contains(number)) {
numbers.add(number);
}
}
Not particularly efficient if numbers is long, because contains on a list can take time proportional to the length of the list.
The time/space trade-off would be creating a set from numbers, because sets have cheap contains:
var alsoNumbers = numbers.toSet(); // Also linear, but only happens once.
for (var number in moreNumbers) {
if (alsoNumbers.add(number)) { // true if elements was added
numbers.add(number);
}
}
(Using add instead of contains ensures that you update the set with new values, so you won't add the same new value twice.)
If you could just make numbers a Set to begin with, it would be much easier to avoid duplicates, just do numbers.addAll(moreNumbers).

How cascading modifies original object?

var intList = [3, 2, 1];
var sorted = intList..toList()..sort(); // [1, 2, 3]
var sorted2 = intList..toList().sort(); // [3, 2, 1]
Why my original list is also being modified in first sort and which list is being sorted in second sort?
NOTE: I'm not looking for the correct way to do it which is this:
var sorted = intList.toList()..sort(); // [1, 2, 3]
x..y evalutes to x. Cascade chains are evaluated left-to-right, so x..y..z is the same as (x..y)..z. Your first example therefore makes calls to toList() and to sort() on the original object.
Member access (.) has higher precedence than the cascade operator (..). Your second example calls sort() on the copy returned by toList(), not on the original object.

Convert nested list (2d list) to one list of elements using built-in methods like map() in Dart

How can I convert 2d list to 1d list with all the elements in dart?
I have this 2d List:
List<List<int>> list2d = [[1, 2], [3, 4]];
What I want is:
List<int> list1d = [1, 2, 3, 4];
By converting the first one (2d) to the second (1d) but without writing any (for/while) loops code, if there any built-in methods like map()/where()/cast()/...etc.
Any ideas?
As other have pointed out, expand does what you want
var list2d = [[1, 2], [3, 4]];
var list1d = list2d.expand((x) => x).toList();
You can also, and perhaps preferably, use a list literal:
var list1d = [for (var list in list2d) ...list];
In general, iterable.expand((x) => e).toList() is equivalent to [for (var x in iterable) ...e].
Simply by using the reduce function like this:
List<int> list1d = list2d.reduce((value, element) {
value.addAll(element);
return value;
});
Definition:
List<T> reduce(List<T> Function(List<T>, List<T>) combine);
You can just use the .expand method:
List<int> list1d = list2d.expand((e) => e).toList();

Is it possible to initialize a List on one line in Dart? (it's called a collection initializer in c#)

Is it possible to initialize a list on one line in Dart? Something like the following...
List<int> options = new List<int>{ 1,2,5,9 };
(this is possible in c# and is called a collection initializer)
Yes:
List<int> options = [1, 2, 5, 9];
I'd recommend reading:
https://api.dartlang.org/stable/1.24.3/dart-core/List-class.html
Yes, you can do it using the List.unmodifiable constructor:
var options = new List.unmodifiable([3,6,7,8]);
Or by using the List.from constructor:
var options = new List.from([3,6,7,8]);
Or just like this:
var options = [5,7,9,0];
There are also available List.filled and List.generate factory constructors:
List<int?> s = List.filled(5, 10, growable: true); // [10, 10, 10, 10, 10]
This creates list of length 5, of type int or null, and initializes each element with 10. This list is growable, which means its length can be changed with a setter:
s.length = 10;
s[8] = 2; // [10, 10, 10, 10, 10, null, null, null, 2, null]
After changing the list length, new elements will be initialized with null. If the list element type is not-nullable this will cause Exception.
List.generate generates a list of values.
var n = List.generate(5, (index) => 0); // [0, 0, 0, 0, 0]
The created list is fixed-length, and each element is set to 0.
List<int?> n = List.generate(5, (index) => index * index, growable: true); // // [0, 1, 4, 9, 16]
If we want to create growable list (i.e. we set growable to true) we need to explicitly choose non-nullable type eg. int? as we did here, otherwise increasing list length will raise exception. This stands for both List.generate and List.filled factories.
Good reads about those are:
https://api.dart.dev/stable/1.24.3/dart-core/List/List.generate.html
and
https://api.dart.dev/stable/1.24.3/dart-core/List/List.filled.html
var vals = <int>[1, 2, 3];
var vals2 = List<int>()..addAll([1, 2, 3]);
var vals3 = List<int>.of([1, 2, 3]);
Note that when we don't provide a type, we in fact create a list of a
dynamic type. Also, the new keyword is optional.
Square brackets define a List
var listOfInt = [1,2,3]
Curly brackets define a Set
var setOfInt = {1,2,3};
Curly brackets with colons define a Map
var mapOfIntString = {1: "a", 2: "b"};
It is possible to specify the type explicitly.
var list = <int>[1,2,3]
var setOfInt = <int>{1,2,3};`
var map = <int,String>{1: "a", 2: "b"};
Initialize empty list
List<int> options = [];
Initialize filled list
List<int> options = [1,2,5,9];

How to append elements into Erlang list when the list size is unknown

How to append elements into Erlang list data type when size of the list is unknown.
Sample elements: 1, 2, 3, 4.
The final list should be L = [1,2,3,4].
The list in Erlang is dynamic-length, so you don't need to specify its final size in advance.
Also you can add new element to list this way:
List0 = [],
List1 = [4|List0],
List2 = [3|List1],
List3 = [2|List2],
List4 = [1|List3],
%% => List4 = [1, 2, 3, 4].

Resources