Is there a better/faster way in Dart to rotate a list?
List<Object> rotate(List<Object> l, int i) {
i = i % l.length;
List<Object> x = l.sublist(i);
x.addAll(l.sublist(0, i));
return x;
}
Could be simplified a bit
List<Object> rotate(List<Object> list, int v) {
if(list == null || list.isEmpty) return list;
var i = v % list.length;
return list.sublist(i)..addAll(list.sublist(0, i));
}
If you want to shift instead of rotate you can simply use the removeAt function:
List<int> list = [ 1, 2, 3 ];
int firstElement = list.removeAt(0);
print(list); // [ 2, 3 ]
print(firstElement); // 1
From the docs:
Removes the object at position [index] from this list.
This method reduces the length of this by one and moves all later objects down by one position.
Returns the removed value.
The [index] must be in the range 0 ≤ index < length. The list must be growable.
Here are some more useful JS shims.
Related
I am trying to find the distance of a node from the root of a binary tree but I am getting right answer up to only 3 branches only. like for the node(4) I am getting 3 and for the node (9) and node(10) I am getting 3
#include<bits/stdc++.h>
using namespace std;
struct node
{
int data;
struct node *left;
struct node *right;
node(int val)
{
data = val;
left = NULL;
right = NULL;
}
};
int find_node(node* root,int n)
{
static int length=1;
if (root== NULL)
{
return 0;
}
if (root->data==n)
{
return length;
}
length=length+(find_node(root->left,n)||find_node(root->right,n));
// find_node(root->left,n);
// find_node(root->right,n);
return length;
}
int main ()
{
struct node* root = new node(1);
root->left = new node(2);
root->right = new node(3);
root->left->left = new node(4);
root->left->right = new node(5);
root->right->left = new node(6);
root->right->right = new node(7);
root->right->right->right = new node(9);
root->right->right->right->right = new node(10);
cout <<find_node(root,10);
return 0;}
When your code reaches the first leaf node (with data 4), the following assignment will assign 1:
length=length+(find_node(root->left,n)||find_node(root->right,n));
Because the expression resolves to 1+(0||0), i.e. 1. And so 1 is returned.
The caller (at the node with data 2) will thus receive this 1, and so the above statement will yield 2, since it resolves to 1+(1||......), which is 2 -- the second operand of || is not evaluated.
The parent caller (at the node with data 1), will thus receive this 2. The assignment there resolves to 1+(2||.....), which is again 2 -- realise that || is a logical operator, so it can only evaluate to a boolean value (i.e. 0 or 1).
The issues
In summmary:
You should not use || as it can only evaluate to 0 or 1, losing the actual value from recursion that you need.
You should not use a static variable. For one, it would not reset if you would make a second call to this function from the main program code. Instead, every recursive call should just "mind its own business" and return the depth of n from the given root. The caller should add 1 to that if n was found.
Correction
int find_node(node* root, int n)
{
if (root == NULL)
{
return 0;
}
if (root->data == n)
{
return 1;
}
int length = find_node(root->left, n);
if (!length)
{
length = find_node(root->right, n);
}
if (!length)
{
return 0;
}
return 1 + length;
}
I am using fold on an array which hasn't been assign to a variable and want to check whether the element is the last value. With a conventional for loop I can do this:
List<int> ints = [1, 2, 3];
int sum = 0;
for (int num in ints]) {
if (num != ints.last) {
sum = sum + num;
}
}
print(sum);
Is it possible to do this with fold instead?
int foldSum = [1, 2, 3].fold(0, (int prev, element) => prev + element);
print(foldSum);
I can't find any way of check when fold is at the last value. Note: this is a simplified example of my problem and the reason the list isn't assigned to a variable (allowing me to use .last) is because it is the result of a call to .map().
For completeness, below is the actual code (which won't obviously won't be runnable in isolation but will help illustrate my problem) I am trying to convert to use .map and .fold:
String get fieldsToSqlInsert {
String val = "";
for (Column column in columns) {
if (data.containsKey(column.name)) {
val = '$val "${data[column.name]}"';
} else {
val = "$val NULL";
}
if (column != columns.last) {
val = "$val,";
}
}
return val;
}
But it doesn't work because I don't know how to check when fold is at the final element:
String get fieldsToSqlInsert => columns
.map((column) =>
data.containsKey(column.name) ? data[column.name] : "NULL")
.fold("", (val, column) => column != columns.last ? "$val," : val);
If you simply want to exclude the last element from further calculation, you can just use take to do so:
String get fieldsToSqlInsert => columns.take(columns.length - 1)...
I need to get all possible subsets of an array.
Say I have this:
<int>[1, 2, 3]
How do I get this?
[], [1], [2], [3],[1, 2], [2, 3], [1, 3], [1, 2, 3]
I am interested in all subsets. For subsets of specific length, refer to the following questions:
How to find all subsets of a set in JavaScript?
Here is my take on it, with only native function as in your link:
List getAllSubsets(List l) => l.fold<List>([[]], (subLists, element) {
return subLists
.map((subList) => [
subList,
subList + [element]
])
.expand((element) => element)
.toList();
});
If you want a specific size:
List getSizedSubsets(List l, int size) =>
getAllSubsets(l).where((element) => element.length == size).toList();
I'd probably go with something simple like:
Iterable<Set<E>> subsets<E>(Set<E> elements) sync* {
if (elements.length >= 32) {
// Otherwise there'll be more than 2^32 subsets. And bitops will overflow in JS.
throw ArgumentError.value(elements, "elements", "must have less than 32 elements");
}
var list = [...elements];
var subsetCount = 1 << list.length;
for (var i = 0; i < subsetCount; i++) {
yield {
for (var j = 0, bit = 1; j < elements.length; j++, bit <<= 1)
if (i & bit != 0) list[j]
};
}
}
Another approach is to only have one set, and then update it iteratively to contain different elements. It's possible to go through all the sets doing only single-element changes on each step (using Gray-code):
/// Iterates a set through all combinations of its elements.
///
/// Adds and removes elements from [set] to make it iterate through all
/// possible combinations of its initial elements.
/// The current value of the iterator is always [set].
/// If iterated through to the end, the [set] ends up with all its original elements.
Iterable<Set<E>> subsets<E>(Set<E> set) sync* {
if (set.length >= 32) {
throw ArgumentError.value(set, "set", "must have less than 32 elements");
}
var list = [...set];
var prev = 0;
var counter = 0;
do {
yield set;
var next = ++counter ^ (counter >> 1);
var bit = prev ^ next; // One bit set.
var index = bit.bitLength - 1;
if (index >= list.length) index = 0;
var element = list[index];
if (next & bit == 0) {
set.add(element);
} else {
set.remove(element);
}
prev = next;
} while (set.length < list.length);
}
How can I find the closest value in a list, which will return me the higher value?
Example: List of [3,7,12,19] if my value is 8 how can I get the nearest(larger) value 12? i want this logic in dart.
Just filter the List only for the values higher or equal to your number and get the lowest value:
var n = 8; // Number to match
var l = [3, 7, 12, 19]; // List of values
var greater = l.where((e) => e >= n).toList()..sort(); //List of the greater values
print(greater.first); // Print the first value. -> 12
To get Closest Value of number
import 'dart:math';
import 'dart:collection';
void main(){
List<double> value = [1,4,6,3,7,9,12,34,12,-12,-91];
print(value.getCloseValue(8)); // 7
print(value.getCloseValue(6)); // 6
print(value.getCloseValue(-11)); // -12
}
extension on List<num> {
num getCloseValue(num x) {
if (isEmpty) return 0;
Map<num, num> values = {};
forEach((e) {
values[e] = (e - x).abs();
});
var sortedKeys = values.keys.toList(growable:false)
..sort((k1, k2) => values[k1]!.compareTo(values[k2]!));
final sortedMap = LinkedHashMap
.fromIterable(sortedKeys, key: (k) => k, value: (k) => values[k]);
return sortedMap.keys.first;
}
}
List<int> arr = [6, 12, 11, 18, 24,5,6,99,10,9];
arr.sort((a, b) => a.compareTo(b));
print(arr);
print(Utils.getNextLargerNumber(8, arr));
and below is the logic:
static int getNextLargerNumber(int number, List<int> array)
{
for (var i = 0; i < array.length; i++) {
if (number < array[i]) {
return array[i];
}
}
return -1;
}
Mattia's answer is already good enough. (although the list cant have the length 0 and it might be not as efficient, as you have a where() as well as sort() in there). Here is a different approach, that solves those concerns:
Nearest value to target (larger favored)
final nearestLarger = list.isEmpty ? null : list.reduce(
(a, b) => (a-target).abs() < (b -target).abs() ? a : b);
Nearest value to target (smaller favoured)
final nearestSmaller = list.isEmpty ? null : list.reduce(
(a, b) => (a-target).abs() <= (b -target).abs() ? a : b);
Note that both functions retrieve the nearest value to the target, but in case of ambiguity (eg. [3,4,5]) either the bigger or smaller value is favored.
How do you get the min and max values of a List in Dart.
[1, 2, 3, 4, 5].min //returns 1
[1, 2, 3, 4, 5].max //returns 5
I'm sure I could a) write a short function or b) copy then sort the list and select the last value,
but I'm looking to see if there is a more native solution if there is any.
Assuming the list is not empty you can use Iterable.reduce :
import 'dart:math';
main(){
print([1,2,8,6].reduce(max)); // 8
print([1,2,8,6].reduce(min)); // 1
}
If you don't want to import dart: math and still wants to use reduce:
main() {
List list = [2,8,1,6]; // List should not be empty.
print(list.reduce((curr, next) => curr > next? curr: next)); // 8 --> Max
print(list.reduce((curr, next) => curr < next? curr: next)); // 1 --> Min
}
You can now achieve this with an extension as of Dart 2.6:
import 'dart:math';
void main() {
[1, 2, 3, 4, 5].min; // returns 1
[1, 2, 3, 4, 5].max; // returns 5
}
extension FancyIterable on Iterable<int> {
int get max => reduce(math.max);
int get min => reduce(math.min);
}
An example to get Min/Max value using reduce based on condition for a list of Map objects
Map studentA = {
'Name': 'John',
'Marks': 85
};
Map studentB = {
'Name': 'Peter',
'Marks': 70
};
List<Map> students = [studentA, studentB];
// Get student having maximum mark from the list
Map studentWithMaxMarks = students.reduce((a, b) {
if (a["Marks"] > b["Marks"])
return a;
else
return b;
});
// Get student having minimum mark from the list (one liner)
Map studentWithMinMarks = students.reduce((a, b) => a["Marks"] < b["Marks"] ? a : b);
Another example to get Min/Max value using reduce based on condition for a list of class objects
class Student {
final String Name;
final int Marks;
Student(this.Name, this.Marks);
}
final studentA = Student('John', 85);
final studentB = Student('Peter', 70);
List<Student> students = [studentA, studentB];
// Get student having minimum marks from the list
Student studentWithMinMarks = students.reduce((a, b) => a.Marks < b.Marks ? a : b);
If your list is empty, reduce will throw an error.
You can use fold instead of reduce.
// nan compare to any number will return false
final initialValue = number.nan;
// max
values.fold(initialValue, (previousValue, element) => element.value > previousValue ? element.value : previousValue);
// min
values.fold(initialValue, (previousValue, element) => element.value < previousValue ? element.value : previousValue);
It can also use to calculate sum.
final initialValue = 0;
values.fold(initialValue, (previousValue, element) => element.value + previousValue);
Although fold is not cleaner than reduce for getting min/max, it is still a powerful method to do more flexible actions.
For empty lists: This will return 0 if list is empty, the max value otherwise.
List<int> x = [ ];
print(x.isEmpty ? 0 : x.reduce(max)); //prints 0
List<int> x = [1,32,5];
print(x.isEmpty ? 0 : x.reduce(max)); //prints 32
int minF() {
final mass = [1, 2, 0, 3, 5];
mass.sort();
return mass[0];
}
void main() {
firstNonConsecutive([1,2,3,4,6,7,8]);
}
int? firstNonConsecutive(List<int> arr) {
var max = arr.reduce((curr, next) => curr > next? curr: next);
print(max); // 8 --> Max
var min = arr.reduce((curr, next) => curr < next? curr: next);
print(min); // 1 --> Min
return null;
}
If you need a more sophisticated min/max, such as finding an object with a min/max of a field, or use of a comparison predicate, use minBy() and maxBy() from the collection package:
import 'package:collection/collection.dart';
class Person {
final String name;
final int age;
Person(this.name, this.age);
#override
String toString() => '$name (age $age)';
}
main() {
final alice = Person('Alice', 30);
final bob = Person('Bob', 40);
final chris = Person('Chris', 25);
final dan = Person('Dan', 35);
final people = [alice, bob, chris, dan];
print('Youngest is ${minBy(people, (e) => e.age)}');
print('Oldest is ${maxBy(people, (e) => e.age)}');
print('First alphabetically is ${minBy(people, (e) => e.name)}');
print('Last alphabetically is ${maxBy(people, (e) => e.name)}');
print('Largest name length times age is ${maxBy(people, (e) => e, compare: (a, b) => (a.name.length * a.age).compareTo(b.name.length * b.age))}');
}
Output:
Youngest is Chris (age 25)
Oldest is Bob (age 40)
First alphabetically is Alice (age 30)
Last alphabetically is Dan (age 35)
Largest name length times age is Alice (age 30)```