Why can't I assign a shuffled array to a new array - dart

Why can't I assign a shuffled array to a new array?
For example, this is my list:
List nums = [1, 2, 3];
List newlist=nums.shuffle();
However, this does not work for me.

Because shuffle() on List does not return anything (which is indicated by void which means the method does not return anything usable) but are instead shuffling the list you are calling the method on.
void shuffle([Random? random])
Shuffles the elements of this list randomly.
https://api.dart.dev/stable/2.15.1/dart-core/List/shuffle.html
If you want to output your nums list after it have been shuffled, you just need to print nums like this after the nums.shuffle() call:
void main() {
final nums = [1, 2, 3];
nums.shuffle();
print(nums); // [2, 3, 1]
}
If you want to have a new list there is shuffled and based on another list, you can do something like this (the .. is called a cascade call, you can read more about it here: https://dart.dev/guides/language/language-tour#cascade-notation):
void main() {
final nums = [1, 2, 3];
final shuffeledNums = nums.toList()..shuffle();
print(nums); // [1, 2, 3]
print(shuffeledNums); // [2, 1, 3]
}
Which is the same as this without the use of cascade:
void main() {
final nums = [1, 2, 3];
final shuffeledNums = nums.toList();
shuffeledNums.shuffle();
print(nums); // [1, 2, 3]
print(shuffeledNums); // [2, 1, 3]
}

Related

Use reduce method in dart to group consecutive elements in the list like in Javascript

I have following codes in javascript
var ArrayLogs = [1, 3, 5, 4, 9, 11, 0, -4, -10];
var newLogArrays = [];
ArrayLogs.reduce(function(result, value, index, array) {
if (index % 2 === 0){
newLogArrays.push(array.slice(index, index + 2));
}
return newLogArrays;
}, []);
Above method outputs:
[[1,3],[5,4],[9,11],[0,-4],[-10]]
I am looking equivalent code in Dart, I know there is reduce method in dart as well, but I am not sure how to use to get similar result as javascript.
Any help will be highly appreciated.
Thanks
If you just want to do it using Dart only, you can do something like the following:
void main() {
final arrayLogs = [1, 3, 5, 4, 9, 11, 0, -4, -10];
final result = arrayLogs.fold<List<List<int>>>([], (list, element) {
if (list.isEmpty || list.last.length > 1) {
return list..add([element]);
} else {
return list..last.add(element);
}
});
print(result);
// [[1, 3], [5, 4], [9, 11], [0, -4], [-10]]
}
I am sure there are some packages which can do this more automatically or cleaner.

How can i find sum of three element in a given away

Is there a method we use to reach the desired number in an array given in dart language.. I can do this for binary ones, but I can't do it for a code that finds the sum of 3 or more elements
For example
Input: candidates = [10,1,2,7,6,1,5], target = 8
Output:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]
this is the my code i have done until now
void main() {
var candidates = [10, 1, 2, 7, 6, 1, 5], target = 8;
var answer = [];
for (int i = 0; i < candidates.length; i++) {
for (int j = 0; j < candidates.length; j++) {
if (candidates[i] + candidates[j] == target && i != j && i < j) {
answer.add([candidates[i], candidates[j]]);
}
}
}
}
I am sure this can be done more efficient but since the solution is for some Leetcode assignment, I don't really want to spend too much time on optimizations.
I have tried added some comments in the code which explains my way of doing it:
void main() {
getSumLists([10, 1, 2, 7, 6, 1, 5], 8).forEach(print);
// [5, 1, 2]
// [1, 6, 1]
// [1, 7]
// [6, 2]
getSumLists([2, 5, 2, 1, 2], 5).forEach(print);
// [2, 1, 2]
// [5]
}
Iterable<List<int>> getSumLists(
List<int> candidates,
int target, {
List<int>? tempAnswer,
int sum = 0,
}) sync* {
// We cannot use default value in parameter since that makes list const
final tempAnswerNullChecked = tempAnswer ?? [];
if (sum == target) {
// We got a result we can return.
// OPTIMIZATION: If you know the returned list from each found result is not
// being used between found results, you can remove the `.toList()` part.
yield tempAnswerNullChecked.toList();
} else if (sum > target) {
// No need to search further in this branch since we are over the target
return;
}
// Make a copy so we don't destroy the input list but also so it works even
// if provided list as input is non-growing / non-modifiable
final newCandidates = candidates.toList();
while (newCandidates.isNotEmpty) {
// We take numbers from the end of the list since that is more efficient.
final number = newCandidates.removeLast();
// Recursive call where we return all results we are going to find given
// the new parameters
yield* getSumLists(
newCandidates,
target,
tempAnswer: tempAnswerNullChecked..add(number),
sum: sum + number,
);
// Instead of creating a new tempAnswerNullChecked, we just reuse it and
// make sure we remove any value we are temporary adding
tempAnswerNullChecked.removeLast();
// Ensure we don't get duplicate combinations. So if we have checked the
// number `1` we remove all `1` so we don't try the second `1`.
newCandidates.removeWhere((element) => element == number);
}
}

Removing duplicates from list of lists

I'm having issues attempting to remove duplicate lists within a list. For example, using the list below, I need to remove one of the [2, 9] elements from the list.
List listOfLists = [[1, 5], [2, 9], [10, 12], [-1, 4], [2, 9]];
I have tried using toSet, but it only seems to work with a list of int or strings:
List uniqueLists = listOfLists.toSet().toList();
I have been stuck on this all morning, I'm sure its something simple, but the solution isn't coming to me. Any help would be appreciated.
The issue is that == for lists is reference equality, not based on the value of the lists.
for example if you run this program:
void main() {
print([2, 9] == [2, 9]);
}
it will print false.
You can create a HashSet (or LinkedHashSet if you want to preserve the order) with custom equals and hashcode functions.
import 'dart:collection';
import 'package:collection/collection.dart';
void main() {
List<List<int>> listOfLists = [
[1, 5],
[2, 9],
[10, 12],
[-1, 4],
[2, 9],
];
Set<List<int>> uniqueLists = HashSet<List<int>>(
equals: const ListEquality().equals,
hashCode: const ListEquality().hash,
)..addAll(listOfLists);
print(uniqueLists);
}
This solution uses the collection package for the ListEquality class.
This solution traverses the list backwards, and removes the last item when a duplicate is found. To compare lists, _listsAreEqual is used which is taken from this answer.
Less elegant compared to other solutions, but it does not require any additional packages.
bool _listsAreEqual(list1, list2) {
var i=-1;
return list1.every((val) {
i++;
if (val is List && list2[i] is List) {
return _listsAreEqual(val,list2[i]);
} else {
return list2[i] == val;
}
});
}
List _removeDuplicates(list) {
for (var i=list.length-1; i>0; i--) {
for (var j=i-1; j>=0; j--) {
if (_listsAreEqual(list[i], list[j])) {
list.removeAt(i);
break;
}
}
}
return list;
}
void main(){
List listOfLists = [[1, 5], [2, 9], [10, 12], [-1, 4], [2, 9]];
List uniqueLists = _removeDuplicates(listOfLists);
//List uniqueLists = _removeDuplicates(List.from(listOfLists)); // leave original list unmodified
print(uniqueLists);
}
If you do not want the original list to be modified, use the commented statement instead to create a copy of the original list.
Thank you for your help. Not sure why I didn't find this previously, but this does the trick perfectly.
List uniqueList = listOfLists.map((f) => f.toString()).toSet().toList().map((f) => json.decode(f) as List<dynamic>).toList();

Dart : How to get second to last item in a List

I would like to get the second to last item in a List, similarly than with getter last.
I tried the following :
final list = [1, 2, 3, 4, 5];
final secondToLast = (list..removeLast()).last; // Mutates the List
However it mutates the List.
There is many options available (however you should make sure that list is not null and has at least 2 elements) :
final list = [1, 2, 3, 4, 5];
// Works only for Lists
final secondToLast = list[list.length - 2];
final secondToLast = list.reversed.elementAt(1);
final secondToLast = list.reversed.skip(1).first;
// Works for any Iterable
final secondToLast = list.elementAt(list.length - 2);
To get something similar to last, you can write an extension on Iterable :
extension CustomIterable<T> on Iterable<T> {
T? get secondToLast {
return this == null || length < 2 ? null : elementAt(length - 2);
}
}

Iterating over a complex collection in Dart

I would like to be able to iterate over this collection.
import "package:collection/collection.dart";
main() {
EqualityMap edges = new EqualityMap.from(const ListEquality(), {
[1, 'a']: [2, 3],
[2, 'a']: [2],
[3, 'b']: [4, 3],
[4, 'c']: [5]
});
}
I am doing a recursive function so this is not allowed.
edges.keys.forEach((m) {
// some more code
return something;
});
Is it possible to achieve something similar to this?
for(var edge in edges)
Something like this should work:
for (var edgeKey in edges.keys) {
var edge = edges[edgeKey];
// do something
}

Resources