I can map list in Dart:
[1,2,3].map((e) => e + 1)
but how can I flatMap this list?
Code presented below does not work.
[1,2,3].flatMap((e) => [e, e+1])
expand method is equivalent to flatMap in Dart.
[1,2,3].expand((e) => [e, e+1])
What is more interesting, the returned Iterable is lazy, and calls fuction for each element every time it's iterated.
Coming from Swift, flatMap seems to have a little different meaning than the OP needed. This is a supplemental answer.
Given the following two dimensional list:
final list = [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4]];
You can convert it into a single dimensional iterable like so:
final flattened = list.expand((element) => element);
// (1, 2, 2, 3, 3, 3, 4, 4, 4, 4)
Or to a list by appending toList:
final flattened = list.expand((element) => element).toList();
// [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
Related
When i have list
[1, 2, 3, 4, 5, 6, 7]
i want to get 3 random elements from list
e.g
[1, 3, 4] or [4, 5, 1] or [3, 2, 5]
how can i solve that simply
is there any dart library??
The previous solution is good but could have been written in a more generic way so we don't loose the type information of the List. Also, take does not return a List but instead Iterable.
I have rewritten the code to be more generic and shorter by using the cascade operator. I am not sure if you want a List or Iterable as output so I have made multiple solutions:
void main() {
final items = [1, 2, 3, 4, 5, 6, 7];
print(pickRandomItems(items, 3)); // (7, 4, 3)
print(pickRandomItemsAsList(items, 3)); // [2, 4, 5]
print(pickRandomItemsAsListWithSubList(items, 3)); // [1, 3, 6]
print(items); // [1, 2, 3, 4, 5, 6, 7] (just to show that the original List is untouched)
}
Iterable<T> pickRandomItems<T>(List<T> items, int count) =>
(items.toList()..shuffle()).take(count);
List<T> pickRandomItemsAsList<T>(List<T> items, int count) =>
(items.toList()..shuffle()).take(count).toList();
List<T> pickRandomItemsAsListWithSubList<T>(List<T> items, int count) =>
(items.toList()..shuffle()).sublist(0, count);
Instead of using take in pickRandomItemsAsList you can instead use sublist. But the catch with subList is that if the length are greater than the List it will give an error but with take you just get all the elements in the List shuffled.
Simply shuffle list and take sublist (slice):
List pickRandomItems(List items, int count) {
final list = List.from(items); // cloning original list
list.shuffle(); // shuffling items
return list.take(count); // taking N items
}
List items = [1, 2, 3, 4, 5, 6, 7];
print(pickRandomItems(items, 3));
I have an array say [1,2,3,4,5,6,7,8]. I need to take an input from the user and remove the last input number of array elements and append it to the front of the array. This is what I have achieved
def test(number, array)
b = array - array[0...(array.length-1) - number]
array = array.unshift(b).flatten.uniq
return array
end
number = gets.chomp_to_i
array = [1,2,3,4,5,7,8,9]
now passing the argument to test gives me the result. However, there are two problems here. first is I want to find a way to do this append on the front without any inbuilt method.(i.e not using unshift).Second, I am using Uniq here, which is wrong since the original array values may repeat. So how do I still ensure to get the correct output? Can some one give me a better solution to this.
The standard way is:
[1, 2, 3, 4, 5, 7, 8, 9].rotate(-3) #=> [7, 8, 9, 1, 2, 3, 4, 5]
Based on the link I supplied in the comments, I threw this together using the answer to that question.
def test(number, array)
reverse_array(array, 0, array.length - 1)
reverse_array(array, 0, number - 1)
reverse_array(array, number, array.length - 1)
array
end
def reverse_array(array, low, high)
while low < high
array[low], array[high] = array[high], array[low]
low += 1
high -= 1
end
end
and then the tests
array = [1,2,3,4,5,7,8,9]
test(2, array)
#=> [8, 9, 1, 2, 3, 4, 5, 7]
array = [3, 4, 5, 2, 3, 1, 4]
test(2, array)
#=> [1, 4, 3, 4, 5, 2, 3]
Which I believe is what you're wanting, and I feel sufficiently avoids ruby built-ins (no matter what way you look at it, you're going to need to get the value at an index and set a value at an index to do this in place)
I want to find a way to do this append on the front without any inbuilt method
You can decompose an array during assignment:
array = [1, 2, 3, 4, 5, 6, 7, 8]
*remaining, last = array
remaining #=> [1, 2, 3, 4, 5, 6, 7]
last #=> 8
The splat operator (*) gathers any remaining elements. The last element will be assigned to last, the remaining elements (all but the last element) are assigned to remaining (as a new array).
Likewise, you can implicitly create an array during assignment:
array = last, *remaining
#=> [8, 1, 2, 3, 4, 5, 6, 7]
Here, the splat operator unpacks the array, so you don't get [8, [1, 2, 3, 4, 5, 6, 7]]
The above moves the last element to the front. To rotate an array n times this way, use a loop:
array = [1, 2, 3, 4, 5, 6, 7, 8]
n = 3
n.times do
*remaining, last = array
array = last, *remaining
end
array
#=> [6, 7, 8, 1, 2, 3, 4, 5]
Aside from times, no methods were called explicitly.
You could create a new Array with the elements at the correct position thanks to modulo:
array = %w[a b c d e f g h i]
shift = 3
n = array.size
p Array.new(n) { |i| array[(i - shift) % n] }
# ["g", "h", "i", "a", "b", "c", "d", "e", "f"]
Array.new() is a builtin method though ;)
Given an array A[] and a number x, check for pair in A[] with sum as x. can anyone help me out on this one in rails?
The ruby array #combination method can give you all combinations of array members of a given number of elements.
[1, 2, 3, 4, 5, 6].combination(2).to_a
=> [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 3], [2, 4], ... [5,6]]
Then you just want to select the elements where they add up to a given number.
[1, 2, 3, 4, 5, 6]combination(2).to_a.select{|comb| comb[0] + comb[1] == 7}
=> [[1, 6], [2, 5], [3, 4]]
To make it work for a different number of combined elements (e.g. 3 instead of 2) you can do...
[1, 2, 3, 4, 5, 6]combination(3).to_a.select{|c| (c.inject(0) {|sum,x| sum + x}) == 7}
This will work for 2, 3, 4, or any number up to the full array size.
It works by
finding combinations of 3
using `#inject' to sum all the elements of each combination
comparing that sum to the target number
You can easily achieve it by own function as:
def sum_as_x?(ary,x)
num=a.find{|e| ary.include?(x-e)}
unless num
puts "not exist"
else
p [x-num,num]
end
end
a = [1,2,3,4,5]
sum_to_x?(a,9)
>> [5, 4]
sum_to_x?(a,20)
>> not exist
I have two arrays of database records.
I'd like to add the second one to the beginning of the first.
I looked into insert, at a specific indexx, but it would result in inserting the second array inside the first one.
It might not be that hard, but thanks in advance for any help.
How is this Array#+ ?
array2 = [1,2,3]
array1 = [11,21]
array2 + array1
# => [1, 2, 3, 11, 21]
Ruby's splat to the rescue:
a = [1, 2, 3]
b = [4, 5, 6]
a.unshift(*b)
a #=> [4, 5, 6, 1, 2, 3]
I found another question on here that told how to get the matching items in 2 arrays like this:
matches = array1 & array2
However I have an array of arrays. like:
[[1,2,3,4],[2,3,4,5],[1,3,4,5]]
In this case I want to return 3 and 4 because they are in all three arrays.
How do I go about doing that?
Thank you!
Like this:
a.reduce(:&)
For example:
>> a = [[1,2,3,4],[2,3,4,5],[1,3,4,5]]
=> [[1, 2, 3, 4], [2, 3, 4, 5], [1, 3, 4, 5]]
>> a.reduce(:&)
=> [3, 4]