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).
Related
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.
the normal list in dart 1d can use with it many methods like insert remove indexOf etc . but in 2d list many of list methods can't work with it ? why an example below
var lista = [1,2,3,4,5] ;
lista.add(6);
print(lista);
Works fine
var listb = [[1,2,3],
[4,5]
];
listb.add(6); // wont add cause the argument type 'int' can't be assigned to the parameter type 'List'.
accept it only when listb.add([6]); but add this as new element in list i want to add in [4,5] a number only ?!
If you want to add to the second list of the lists, just do so:
void main() {
var listb = [[1,2,3], [4,5]];
listb[1].add(6);
print(listb);
}
This prints
[[1, 2, 3], [4, 5, 6]]
You wanted the first list to know that you want to add to the second of it's elements. That is not how programming works, the compiler does not guess what you may want. You have to explicitly tell it what to do.
Im trying to find an easy way to create matrix with self incrementing values i.e., if 3x3 array then it should look like
[[0,1,2],[3,4,5],[6,7,8]]
when I do something like below, I could get all zero's
var arr = Array(repeating: Array(repeating: 0, count: 3), count: 3)
Inorder to acheive, I need to loop through elements and reassign incremented values. Instead of that is there any fast approach I could follow without using for-loop?
A possible approach is to use map() on the range of rows and columns:
let nrows = 3 // Number of rows
let ncols = 3 // Number of columns
let matrix = (0..<nrows).map { row in (0..<ncols).map { col in ncols * row + col } }
print(matrix) // [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
The outer (0..<nrows).map maps each row number to an array (the “row”), and the inner (0..<ncols).map maps each column number to a matrix entry.
With a little bit “tuple magic” you could assign auto-incrementing values:
var entry = 0
let matrix = (0..<nrows).map { _ in (0..<ncols).map { _ in (entry, entry += 1).0 } }
but that's not what I would really recommend.
There is the a Subscripts tutorial on Swift.org showing a Matrix struct example, which I really like
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];
ReactiveCocoa has a collect operator which aggregates all next values into an array until the signal or producer completes then sends that aggregated value. What I need is a progressive collect operator where values will collect into an array until a filter condition is passed at which point the array will be forwarded and the operator will start over again at an empty array and aggregate values all over again.
For example, if given a producer that emits the values 1, 2, 3, 4, 5, 6, 7, 8, 9 in that order and a collectWhile operator:
producer.collectWhile { $0 % 5 == 0 }.on(next: { print($0) })
there'd be two print statements:
[1, 2, 3, 4] and [5, 6, 7, 8, 9]
at which point self would complete and so would the collectWhile operator.
collect is built off of reduce but it uses a private data structure:
/// A reference type which wraps an array to avoid copying it for performance and
/// memory usage optimization.
private final class CollectState<Value> {
var values: [Value] = []
func append(value: Value) -> Self {
values.append(value)
return self
}
}
to avoid copying the aggregate values so I assume I'd probably have to do something similar in my implementation. Any one have any thoughts on how I can accomplish the behavior I'm looking for?