Iterating over a list in groups of two or more - flutter

I like to iterate over a list and split them up in couples like this:
List<String> list = [1,2,3,4,5,6,7,8];
List<Tuple2> listOfTuples = list.take2((value1,value2) => Tuple2(value1,value2));
print(listOfTuples.toString()); // output => [[1,2],[3,4],[5,6],[7,8]]
I know there is a take(count) in dart but I did not find a good example.
I know I can do it with a for loop etc. but I am wondering if there us a more elegant way.

There is nothing built in. The way I'd write this today is:
var list = [1, 2, 3, 4, 5, 6, 7, 8];
var tuples = [
for (int i = 0; i < list.length - 1; i += 2) Tuple2(list[i], list[i + 1]),
];
You could write an extension that gives an api take2 on List that could be used in the way you describe.
extension Take2<T> on List<T> {
List<R> take2<R>(R Function(T, T) transform) => [
for (int i = 0; i < this.length - 1; i += 2)
transform(this[i], this[i + 1]),
];
}

Related

Algolia query by INTERSECTION COUNT with two lists

I need to query some users based on "similar" interests. If a user A has 2 similar interests as user B then it's a match. I want to know if the following query is possible in Algolia.
Lets say I have two objects in some Algolia index with a list property on them (interests):
obj1 = {
interests: ['A', 'B', 'C'],
}
obj2 = {
interests: ['B', 'C', 'D'],
}
And I want to query all objects with interests having at least 2 of the following:
interests: ['A', 'B', 'E']
This should return me just obj1 since is the one having 2 interests alike.
Any ideas?
I'm not sure of an easier way to do this. But let me show my findings
interests: ['A', 'B', 'E']
now to capture your requirement the filters statement should be something like
'(interests:A AND interests:B) OR (interests:A AND interests:E) OR (interests:B AND interests:E)'
which if take as a boolean expression is in the form of AB+AC+BC.
But this particular query cannot be used with algolia according to their docs
For performance reasons, we do not support the following boolean combinations:
...
We limit filter expressions to a conjunction (ANDs) of disjunctions
(ORs). For example you can use filter1 AND (filter2 OR filter3)), but
not ORs of ANDs (e.g. filter1 OR (filter2 AND filter3).
But we can convert the AB+AC+BC to a product of sum format. I used https://www.dcode.fr/boolean-expressions-calculator and obtained the equivalent
(A+B).(A+C).(B+C) which would then be
'(interests:A OR interests:B) AND (interests:A OR interests:E) AND (interests:B OR interests:E)'
The query also depends on how many elements are there in the interests array. For example if interests: ['A', 'E', 'C', 'F'] your final filter query would look in the form
'(interests:A OR interests:E OR interests:C) AND (interests:A OR interests:E OR interests:F) AND (interests:A OR interests:C OR interests:F) AND (interests:E OR interests:C OR interests:F)'
Individual product terms have length of interest array-1 terms
TLDR: '(interests:A OR interests:B) AND (interests:A OR interests:E) AND (interests:B OR interests:E)'
you can use a use a combination generating code and get the filter query.
Here is a JS example based on this solution.
const k_combinations = (set, k) => {
let i, j, combs, head, tailcombs;
if (k > set.length || k <= 0) {
return [];
}
if (k == set.length) {
return [set];
}
if (k == 1) {
combs = [];
for (i = 0; i < set.length; i++) {
combs.push([set[i]]);
}
return combs;
}
combs = [];
for (i = 0; i < set.length - k + 1; i++) {
head = set.slice(i, i+1);
tailcombs = k_combinations(set.slice(i + 1), k - 1);
for (j = 0; j < tailcombs.length; j++) {
combs.push(head.concat(tailcombs[j]));
}
}
return combs;
}
const combinations = (set) => {
let k, i, combs, k_combs;
combs = [];
for (k = 1; k <= set.length; k++) {
k_combs = k_combinations(set, k);
for (i = 0; i < k_combs.length; i++) {
combs.push(k_combs[i]);
}
}
return combs;
}
const generateFilterQuery = (array) => {
const combinationSize = array.length - 1
const combinations = k_combinations(array, combinationSize)
return combinations.map((comb) => `(${comb.map(c => `interests:${c}`).join(" OR ")})`).join(" AND ")
}
console.log(generateFilterQuery(["A","B","E"]))
console.log(generateFilterQuery(["A","B","C","D"]))
console.log(generateFilterQuery(["A","B","C","D","E"]))
After generating the filter query pass it as the value of filters parameter
index.search('',{
filters: generatedQuery
}
).then(({hits}) => console.log(hits))

How to get interpolation values between two list values in flutter

I have two different list values i want get the corresponding one list between value to other list between values. Please look at the list below. Here i have 1st list value of 11 and 15 here i need to find the between values of 12, 13 and 15.
11 value =22
15 value =30
List<double> list1 =[11, 15];
List<double> list2 =[22, 30];
If I understand correct you need the interpolation function to generate values between 2 points:
List<double> interpolate(double start, double end, int count) {
if (count < 2) {
throw Exception("interpolate: illegal count!");
}
final array = List.generate(count + 1, (index) => 0.0);
for (int i = 0; i <= count; ++i) {
array[i] = start + i * (end - start) / count;
}
return array;
}
Usage:
void main() {
final input = [1.0, 15.0];
print(interpolate(input.first, input.last, 4));
}
Result:
[1.0, 4.5, 8.0, 11.5, 15.0]

How to map an array into a List of Vector2s in Flutter for FlutterFlame?

I need to convert an array from Firebase into a List of Vector2s in Flutter for FlutterFlame.
From what I gather from the comments you have an array of integers like this:
final numbers = [1, 2, 3, 4, 5, 6, 1, 43];
You can convert this to a list of Vector2 in many ways, this is one way to do it:
final vectors = [
for(int i = 0; i < numbers.length-1; i+=2)
Vector2(numbers[i].toDouble(), numbers[i+1].toDouble())
];

How to find the Intersection of n arrays

I have n arrays or variable length
arr1 = [1,2,3]
arr2 = [1,3,5,8]
....
How can I compute the intersection of those n arrays ?
Consider checking out underscore.js library. It provides function for what you need and a bunch of other usefull functions.
Example from docs:
_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2]
Simple plain JS implementation can be found here. Same idea in CoffeeScript:
intersect_all = (lists) ->
if lists.length is 0
return []
else return lists[0] if lists.length is 1
partialInt = lists[0]
i = 1
while i < lists.length
partialInt = intersection(partialInt, lists[i])
i++
partialInt
The most efficient way is to use hashsets:
function hashset (elements) {
var i, set = {};
if (!Array.isArray(elements)) return elements;
for (i = 0; i < elements.length; i++) {
set[elements[i]] = true;
}
return set;
};
function intersect (a, b) {
var k
, s1 = hashset(a)
, s2 = hashset(b)
, s3 = {}
for (k in s1) {
if (s2[k]) s3[k] = true;
}
return s3;
};
Object.keys(intersect(arr1,arr2));
// ["1", "3"]
You will find CoffeeScript source of this code, benchmarks for it and some additional information in this question.
If you're going to to intersect huge arrays then I strongly recommend you to use this approach.
Either just use something like _.intersection or study the source of that implementation and rewrite it if you like.

fastest way to find the union and intersection items among two list

which is the fastest way to find the union and intersection between two lists?
i mean.
i have two list say
List<1>
1
2
3
4
Lis<2>
2
3
Finally i need to get output as
List<3>
Not Defined
2
3
Not Defined
Hope i am clear with my requirement.
Please let me know if i am conusing
LINQ already has Union and Intersection. Your example is neither.
var set = new HashSet(list2)
var list3 = List1.Select(x => set.Contains(x) ? x : null).ToList();
Or you could do the following, which just gives you the intersection:
HashSet<int> list1 = new HashSet<int>() { 1, 2, 3, 4 };
HashSet<int> list2 = new HashSet<int>() { 2, 3 };
List<int> list3 = list1.Intersect(list2).ToList();
for (int i = 0; i < list3.Count; i++)
{
Console.WriteLine(list3[i]);
}
Console.ReadLine();