Cannot add elements into list inside map body - dart

When executing the following code , no items added to list named x , Any idea why ?
I know if i loop normally over it, it will work but i just wonder why it behaves like that
List<int> x = [];
List<int> y = [1,2,3,4];
y.map((item) => x.add(item +2));

The .map() method returns a lazily evaluated Iterable:
Returns a new lazy Iterable with elements that are created by calling toElement on each element of this Iterable in iteration order.
Since you don't consume the returned Iterable, it will not trigger the method provided to map() and nothing happens.
You can instead use the forEach() method which will run on each elements in your list immediately.

Related

I have an array a=[1,2,3,4,5,6] and in next line i want array that has only even values in it. Trying to do this by .collect but value is in boolean

a=[1,2,3,4,5,6,7,8]
w=a.collect{|i| i%2==0}
p w
The result is coming to be
[false,true,false,true]
why?
When i am doing
w=a.collect{|i| i+2}
Result is an array like
[3,4,5,6,7,8,9,10,11]
Why? What am i doing wrong?
You don't need map / collect (they are aliases), you need
array.select(&:even?)
or
array.reject(&:odd?)
These methods filter original array, unlike map that performs actions with every element and returns new array of the same length
That's why you get boolean array same length instead of filtering
Please read more in docs:
Array#map, Array#select, Array#reject

Convert string to list of ints

I have a string like this "1, 2, 3, 4, 5, 10, 23, 54"
I can do this by first converting it to list of string
List<String> list = str.split(",");
Then I have to loop the list and cast it to int.
Is it possible to convert the above string to List<int> in one line?
Edit 1:
I tried
List<int> ints = "1,2,3".split(",").map((i) => int.parse(i));
But I got 'MappedListIterable<String, int>' is not a subtype of type 'List'
Edit 2:
I found the solution. But I am not very clear.
List<int> ints = "1,2,3".split(",").map((i) => int.parse(i)).toList();
This solves the problem.
But what is the difference between adding toList() and not adding toList() in dart? Can someone explain please?
When using the Map method, it actually returns a MappedIterable (in this case a MappedListIterable) (The documetation for this) instance instead of List, so you need to cast it into a list instance.
That's why adding toList() is working because it actually converts to MappedListIterable into a List.
List<int> ints = "1,2,3".split(",").map((i) => int.parse(i)).toList();
The map method returns an iterable, not a list. It is lazy, so if you follow map(...) with .first, it will only convert the first element.
If you add .toList(), the you eagerly extract all the values from the iterable and create a list containing those values. Since you were asking for a list, you need to do this (an iterable is not necessarily a list).
Another one-liner would be:
List<int> ints = [for (var n in string.split(",")) int.parse(n)];
Alternatively, you can piggy-back on JSON decoding and do:
import "dart:convert";
...
list<int> ints = jsonDecode("[$string]");

Higher order function sort() used it with other higher order function its working with let content also

So, any reason behind happen this things, because when i perform sort() function with let type at that time xcode give me a compile time error
i tried it in my playgound with only sort function and sort() function with other higher order function.
like so
let name = ["mehul","HeLLi","JeniFER","Ankul"]
name.sort()
error :
Cannot use mutating member on immutable value: 'name' is a 'let' constant
but with other higher order functions
let nameStartingWithBArray = name.filter {$0.first != "B"}.map {$0.uppercased()}.sorted()
now there is no error
Please consider the subtle but crucial difference between sort and sorted
sort has no return value. It sorts in place that means the calling object is mutated.
sorted ( as well as filter and map) returns a new object with the result of the operation.
sort() basically works with the list itself. It modifies the original list in place. The return value is None.
name.sort() sorts the list and save the sorted list.
sorted() works on any iterable that may include list, dict and so on. It returns another list and doesn't modify the original list.
sorted() returns a sorted copy of the list (a new sorted list), without changing the original list.
Keynote : sort() is faster than sorted()
The sort function sorts the collection in place - i.e. it modifies the array, name, on which you call sort.
filter on the other hand returns an array and does not modify the original array.
Compare sort with sorted which again returns a new array and does not modify the original array.
So, you can write
let sortedNames = name.sorted()
sortedNames will be in order, while name will be in the original, unsorted, order.
If you write
var name = ["mehul","HeLLi","JeniFER","Ankul"]
name.sort()
then name will be in order, and because it is declared as var rather than a constant with let the change is permitted.
The sort func you are using is the mutating func, that means sort function internally sort the array in the same variable.
Mutating Func : To modify the properties of your structure or enumeration within a particular method, you can opt in to mutating behavior for that method. The method can then mutate (that is, change) its properties from within the method, and any changes that it makes are written back to the original structure when the method ends.
So. let doesn't allow sort for doing mutating, so you need to make it var.
More ever, if you use sorted(by:) , it returns new array of sorted values. So here you don't get any error.

Dart: DoubleLinkedQueue length after entry prepend

I'm manipulating entries inside a DoubleLinkedQueue via the DoubleLinkedQueueElement.append/prepend methods. This results in the new elements being inserted into the queue, but fails to update the length, and the toList() method results in an error being thrown.
I understand queues are only supposed to have elements added at the start/end, but it looks like the interface should allow for adding in the middle via the entries. I find it hard to believe such a common/well understood data structure would have a bug at this point - so am I using DoubleLinkedQueues incorrectly? Is there another data structure that I should be using? I'm looking to merge values from another iterable into my own sorted iterable - a SplayTreeSet might get me there in n log n time, but a simple merge should get me there in linear time...
Example of code that acts unexpectedly:
main() {
var q = new DoubleLinkedQueue<int>.from([1]);
q.firstEntry().prepend(0);
print('length: ${q.length}');
int i = 0;
for (var qi in q){
print('${i++}: $qi');
}
}
Output:
length: 1
0: 0
1: 1
It looks like the length getter is only pointing to an internal counter. This is done because counting the elements everytime might take very long for long lists.
The internal counter is only updated if you use the methods that directly operate on the list instead of using the prepend method of an element. In your example you should use q.addFirst(0); which results in the length being updates. The .prepend() method just inserts a new element and changes the pointer. Which results in correct traversation of the elements, but the counter is wrong anyway.
Unfortunately it looks like you cannot insert elements in the middle of the list, nor can you make the list recount the elements. You should consider creating a bug over at www.dartbug.com.
// Update:
toList() throws an error because there are more elements than length.

How do I cleanly map / sort / fold / sort / expand using only cascades or chained calls, in Dart?

I would like to perform the following operations on a source list:
map
toList
sort
fold
sort
expand
toList
Some of these methods, like map and toList are chainable, because they return a non-null object. However, the sort method returns void as it operates on a List and does not return a list.
Dart has a method cascade operator, which works great for method calls that do not return this or another object.
I'm having a hard time writing the above sequence of calls without resorting to assigning a variable after the sort and then starting the chain of calls again.
I'd like to write the equivalent of:
return thing
.map(...)
.toList()
.sort(...)
.fold(...)
.sort(...)
.expand(...)
.toList();
The closest I can get is:
var thing
.map(...)
.toList()
..sort(...);
var otherThing = thing
.fold(...)
..sort(...);
var finalThing = otherThing.expand(...).toList();
Is there a better way? How do I "break out" of the cascade and continue on a chain?
Can you add some parens? I guess something like this...
return ((thing
.map(...)
.toList()..sort(...))
.fold(...)..sort(...))
.expand(...)
.toList();

Resources