Updating variables in dart changes both data - flutter

How can I change the value of list2 without changing the value of list1. Changing list2 data updates list1 data.
var list = [1,2,3];
var list1;
var list2;
list1 = list;
list2 = list;
list2[0] = 100;
print(list1); //output [100, 2, 3] // need this to be [1,2,3]
print(list2); //output [100, 2, 3]

Objects are passed by reference. When you do list1 = list; and list2 = list;, you're assigning the reference of list to both list1 and list2. So changing the object at that reference will change the data you see at all of these different variables.
If you want these objects to be modified separately, you need to create a new List instance. This can be done with either List.of or a List literal with the spread operator.
list2 = List.of(list);
or
list2 = [...list];
If you only do this for list2, both list1 and list will still be the same, even if you change only one.
var list = [1, 2, 3];
var list1;
var list2;
list1 = list;
list2 = [...list];
list2[0] = 100;
list1[0] = 200;//list1 is changed here
//But `list` will be changed as well as shown below
print(list); //output [200,2,3]
print(list1); //output [200,2,3]
print(list2); //output [100,2,3]
If you want each of these Lists to be completely separate, you would need to use List.of or a List literal with spread for both list1 and list2.

Use the List.of constructor to assign all elements of list to list2.
Added an example:
var list = [1, 2, 3];
var list1;
var list2;
list1 = list;
// use List.of
list2 = List.of(list1);
list2[0] = 100;
print(
list1); //output [1,2,3]
print(list2); //output [100,2,3]

Related

How to preserve data after flutter List.add() in flutter

Store data in a 1-dimensional List and add() it to a 2-dimensional List.
After add(), .clear() the one-dimensional List.
However, since List refers to an address, clear() loses the address, so the 2D array becomes an empty List. Is there a way to keep the values ​​in a 2D List even after clearing?
List<int> num = [1, 2, 3];
List<List<int> num2 = [];
num2.add(num);
num.clear();
You could use List.from() to perform shallow copy
List<int> num = [1, 2, 3];
List<List<int>> num2 = [];
num2.add(List.from(num));
print(num2); //[[1, 2, 3]]
num.clear();
print(num2); //[[1, 2, 3]]
use trick with toList() method
void main() {
List<int> num1 = [1, 2, 3];
List<List<int>> num2 = [[0,2]] ;
num2.add(num1.toList());
num1.clear();
print(num2); // [[0, 2], [1, 2, 3]]
print(num1); // []
}
You should add list as anonymous list
List<int> num = [1, 2, 3];
List<List<int>> num2 = [];
// add as anonymous list
num2.add(num.toList());
num.clear();
print(num2.length); // 1
print(num.length); // 0
for (var element in num2) {
print(element.length); // 3
}

I want to calculate each number from the array in flutter

I have an array in the flutter
final list = [1, 2, 3, 4, 5];
I want to loop through the array to calculate the sum of all the items in the array,how i can?
Try the following:
final list = [1, 2, 3, 4, 5];
final result = list.reduce((sum, element){
return sum + element;
});
This could do it
final sum = list.fold<int>(0, (previousValue, number) => previousValue + number);

Dart combine two Lists in Alternate manner

I am trying to populate a ListView in Flutter with different sources. So, I have two lists,
list1 = ['a', 'b', 'c']; #The list isn't of numeric type
list2 = ['2', '4'];
Now, I can combine them using the spread operator and get the following output
[a, b, c, 2, 4]
but I want the output to be like -
[a, 2, b, 4, c]
How can this be achieved? What's the most idiomatic approach?
Builtin Iterable has no method zip, but you can write something like:
Iterable<T> zip<T>(Iterable<T> a, Iterable<T> b) sync* {
final ita = a.iterator;
final itb = b.iterator;
bool hasa, hasb;
while ((hasa = ita.moveNext()) | (hasb = itb.moveNext())) {
if (hasa) yield ita.current;
if (hasb) yield itb.current;
}
}
then use zip
final list1 = ['a', 'b', 'c'];
final list2 = ['2', '4'];
final res = zip(list1, list2);
print(res); // (a, 2, b, 4, c)
I guess this:
List list1 = [1, 3, 5];
List list2 = [2, 4];
print([...list1, ...list2]..sort());

Group an array to match another array

I have an array of dates that is grouped by months. I am trying to group another array of values so that it matches the first array. Is that possible?
For example:
array1 = [[1,2,3],[4,5,6]]
array2 = ["one","two","three","four","five","six"]
I would want the second array to be grouped the same as the first array so that they match:
array2 = [["one","two","three"],["four","five","six"]]
The evolution of an idea...
First, a solution for a 2D array:
If you know your array1 is a 2-dimensional array (array of arrays of elements), you can do this by making array2 into an iterator and using map and compactMap to replace the elements:
let array1 = [[1,2,3],[4,5,6]]
let array2 = ["one","two","three","four","five","six"]
var iter = array2.makeIterator()
let array3 = array1.map { arr in arr.compactMap { _ in iter.next() }}
print(array3)
Result:
[["one", "two", "three"], ["four", "five", "six"]]
A more general and generic solution:
Here is a more general solution that uses a sequence instead of array2, that doesn't depend on your knowing ahead of time the layout of array1 or the types of the values of either the array or the sequence:
func remap<S: Sequence>(_ array: [Any], using sequence: S) -> [Any] {
var iter = sequence.makeIterator()
func remap(_ array: [Any]) -> [Any] {
return array.compactMap { value in
if let subarray = value as? [Any] {
return remap(subarray)
} else {
return iter.next()
}
}
}
return remap(array)
}
How this works:
The second array or sequence is turned into an iterator called iter which allows us to get the values in order with repeated calls to iter.next().
Then a second recursive version of remap() is used to convert [Any] into [Any] in a depth-first traversal order. compactMap() is used to replace elements of the array. While replacing the elements of the array, if the element is another array, it recursively calls remap() on that array until it finally gets to values which aren’t arrays. If the element is a non-array element, it replaces it with the next value from the iterator which is serving up the elements of the sequence (or second array) in order. We use compactMap instead of map to handle the fact that iter.next() is returning optional values because it could run out of values in which case it returns nil. In that case, remap() will replace the remaining elements with nothing while still maintaining the structure of the first nested array.
Examples:
// replace Ints with Strings
let array1: [Any] = [1, [2, 3], [4, [5, 6]]]
let array2 = ["one","two","three","four","five","six"]
let array3 = remap(array1, using: array2)
print(array3)
["one", ["two", "three"], ["four", ["five", "six"]]]
// replace Strings with Ints
let array4: [Any] = ["a", ["b", "c"], [[["d"]], "e"]]
let array5 = [1, 2, 3, 4, 5]
let array6 = remap(array4, using: array5)
print(array6)
[1, [2, 3], [[[4]], 5]]
// map letters to numbers starting with 5 using a partial range
print(remap(["a", ["b"], ["c", ["d"]]], using: 5...))
[5, [6], [7, [8]]]
// using stride to create a sequence of even numbers
let evens = stride(from: 2, to: Int.max, by: 2)
print(remap([["a", "b"], ["c"], [["d"]]], using: evens))
[[2, 4], [6], [[8]]]
// an example of not enough values in replacement array
print(remap([["a", "b"], ["c"], [["d"]]], using: [1]))
[[1], [], [[]]]
You can use numpy.array instead of list, like this:
import numpy as np
arr2 = ["one","two","three","four","five","six"]
arr3 = np.array(arr2).reshape(2,3)
arr3
Result:
array([['one', 'two', 'three'],
['four', 'five', 'six']], dtype='<U5')

Transform a list + list of lists into a list of maps [duplicate]

This question already has an answer here:
Scala - Two Lists to Tuple List
(1 answer)
Closed 3 years ago.
How can I transform this:
List(a,b,c)
List(List(1,2,3), List(2,3,1), List(3,2,1))
Into this:
List(a -> List(1,2,3), b -> List(2,3,1), c -> List(3,2,1))
val list1 = List("a","b","c")
val list2 = List(List(1,2,3), List(2,3,1), List(3,2,1))
val res = list1 zip list2 // List((a,List(1, 2, 3)), (b,List(2, 3, 1)), (c,List(3, 2, 1)))
var list_a = List("a","b","c");
var list_b = List(List(1,2,3), List(2,3,1), List(3,2,1));
var new_list = collection.mutable.Map[String, List[Int]]();
for( i <- 0 to list_a.length-1){
new_list += (list_a(i) -> list_b(i));
}
First we define both lists based on the example provided in the answer.
Second, we define the new list we"re trying to generate.
In the for loop, we"re adding new items to the array, based on the definition provided above.