This question already has answers here:
Ruby array access 2 consecutive(chained) elements at a time
(4 answers)
Closed 3 years ago.
Say I have a an array like:
a = [1, 2, 3, 4, 5, 6]
and I have two variables like this:
b = 3
c = 4
I want to do something like this:
a.each do |i|
if(b = = i) and (c == i.next(I don't think I can do this))
return true
end
end
Any help would be appreciated.
Steve G.
each_cons does what you want:
a = [1, 2, 3, 4, 5, 6]
b=3
c=4
a.each_cons(2){|v1, v2| puts(b == v1 && c == v2)}
# output:
# false
# false
# true
# false
# false
a.each_cons(2).include?([b,c])
Don't use
a.each_slice
To get a series of paired objects.
Use each_cons as suggested by steenslag or glenn mcdonald.
Do you need to do it in a loop, or could you simply track if each variable is a member? of the array in question? Or put them into a hash/set and make sure each key is contained? Or keep the loop, and just keep logical-ORing whether or each var is a member? Or add a members? method to Array, and pass in an array to check against, or...
That should be enough ideas to get you started.
Related
This question already has answers here:
Array#each vs. Array#map
(7 answers)
Closed 4 years ago.
What is the difference between this code:
p arr = [1, 2, 3, 4, 5]
p arr.map! { |a| a + 2 }
and this code?
arr = [1, 2, 3, 4, 5]
new_arr = []
arr.each do |n|
new_arr << n + 2
end
p arr
p new_arr
They both result in the same answer. Are they just two different ways to achieve the same solution or is there a process or application difference?
The #map function "invokes the given block once for each element of self, replacing the element with the value returned by the block".
In your second example the #each method modifies each element of the array by adding + 2 and returns the modified array. The second example is based on creating a new array and filling it with modified values from the first array.
The process is pretty much the same, the main difference is that in the first example you permanently modify the array while in the second example you get to keep the first array unchanged and create a new one with modified values.
I would like to find the sum of each row of a multidimensional array, and have the sums an array, e.g., for [[1,2,3],[1,1,1]], I would like to get [6,3].
I tried the following:
arr = [[1,2,3],[3,2,1],[2,1,3]]
print arr.each{|row| row.each{|column| puts column}}
Results:
1
2
3
3
2
1
2
1
3
[[1, 2, 3], [3, 2, 1], [2, 1, 3]]
I am struggling with it. I still don't fully understand each iterators. Any help would be appreciated.
For ruby 2.4.0 or newer
a.map { |suba| suba.sum }
or simply
a.map(&:sum)
for ruby prior to 2.4.0
a.map { |suba| suba.inject(0, :+) }
[[1,2,3],[1,1,1]].map{|a| a.inject(:+)} # => [6, 3]
If there is a possibility that any of the sub-array can be empty, then you need to add the initial 0, as Ursus pointed out.
[[1,2,3],[1,1,1]].map{|a| a.inject(0, :+)} # => [6, 3]
[[1,2,3],[1,1,1]].map { |a| a.inject(0, :+) } # => [6 , 3]
map changes each element to the return value of this elements block
get the sum for each array with inject(:+)
use inject(0, :+) to set 0 instead of the first element as the start value (handles empty inner array)
see:
Enumerable#inject
Enumerable#map
"How to find the sum of each row"
arr = [[1,2,3], [1,1,1]]
print arr.each{|row| <-- here you have each row
So now row contains [1,2,3] initially. As others have mentioned, you can apply a sum here. (You don't need the leading print).
arr.each{|row| puts row.sum}
Result:
6
3
But a better way to do it is with map. As I told a Ruby newbie many years ago, think of map when you want to change every element to something else, in other words a "1:1 mapping" of input to output. In this case the output is row.sum:
sums = arr.map{|row| row.sum}
Result:
[6, 3]
How do you create a for loop like
for (int x=0; x<data.length; x+=2)
in ruby? I want to iterate through an array but have my counter increment by two instead of one.
If what you really want is to consume 2 items from an array at a time, check out each_slice.
[1,2,3,4,5,6,7,8,9].each_slice(2) do |a, b|
puts "#{a}, #{b}"
end
# result
1, 2
3, 4
5, 6
7, 8
9,
Ruby's step is your friend:
0.step(data.length, 2).to_a
=> [0, 2, 4, 6]
I'm using to_a to show what values this would return. In real life step is an enumerator, so we'd use it like:
data = [0, 1, 2, 3, 4, 5]
0.step(data.length, 2).each do |i|
puts data[i]
end
Which outputs:
0
2
4
<== a nil
Notice that data contains six elements, so data.length returns 6, but an array is a zero-offset, so the last element would be element #5. We only get three values, plus a nil which would display as an empty line when printed, which would be element #6:
data[6]
=> nil
That's why we don't usually walk arrays and container using outside iterators in Ruby; It's too easy to fall off the end. Instead, use each and similar constructs, which always do the right thing.
To continue to use step and deal with the zero-offset for arrays and containers, you could use:
0.step(data.length - 1, 2)
but I'd still try working with each and other array iterators as a first choice, which #SergioTulentsev was giving as an example.
(0..data.length).step(2) do |x|
puts x
end
This seems like the closest substitute.
Using Range#step:
a = (1..50).to_a
(1..a.size).step(2).map{|i| a[i-1]} # [1, 3, 5, 7, 9 ...
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Ruby - What is the difference between map, each and collect?
I have looked in Ruby-Doc also but i cant understand the difference between
map
each
iterators.It would be great if you could give an example and explain.
each simply iterates over the given enumerable, running the block for each value. It discards the return value of the block, and each simply returns the original object it was called on:
[1, 2, 3].each do |x|
x + 1
end # => [1, 2, 3]
This is simply a nicer, more universal way of doing a traditional iterating for loop, and each is much preferred over for loops in Ruby (in fact, I don't think I've ever used a for loop in Ruby).
map, however, iterates over each element, using the return value of the block to populate a new array at each respective index and return that new array:
[1, 2, 3].map do |x|
x + 1
end # => [2, 3, 4]
So it “maps” each element to a new one using the block given, hence the name “map”. Note that neither each nor map themselves modify the original collection. This is a concise, functional alternative to creating an array and pushing to it in an iterative loop.
each returns the original object. It's used to run an operation using each element of an array without collecting any of the results. For example, if you want to print a list of numbers, you might do something like this:
arr = [1, 2, 3, 4]
arr.each { |n| puts n }
Now, that puts method above actually returns nil. Some people don't know that, but it doesn't matter much anyway; there's no real reason to collect that value (if you wanted to convert arr to strings, you should be using arr.map(&:to_s) or arr.map { |n| n.to_s }.
map returns the results of the block you pass to it. It's a great way to run an operation on each element in an array and retrieve the results. If you wanted to multiple every element of an array by 2, this is the natural choice. As a bonus, you can modify the original object using map!. For example:
arr = [1, 2, 3, 4]
arr.map! { |n| n * 2}
# => [2, 4, 6, 8]
I have two list
a = [1, 2, 3, 4, 1, 2]
b = a.uniq # b = [1, 2, 3, 4]
c = a - b
the result gets c = []
I expects the result c = [1, 2]
How can I get this?
This is the expected result according to the Array documentation.
If you want to get the values which have multiple occurrences within the array you could something like:
a.uniq.keep_if {|v| a.count(v) > 1}
If Ruby 1.8 is used, keep_if is not available, so you need to use something like:
a.uniq.delete_if {|v| a.count(v) == 1}
(Both methods keep a intact)
If you want to get elements from array which appears more than once you can use following code:
a.delete_if { |x| a.count(x) <= 1 }.uniq
If you want to perform sub operation on two arrays based on elements position you can use following code:
i = 0
a.drop_while { |x| b[i+=1] == x }.uniq
From the documentation
Array Difference—Returns a new array that is a copy of the original array, removing any items that also appear in other_ary. (If you need set-like behavior, see the library class Set.)
You are looking for all duplicates or the opposite of uniq? Maybe this link will help: Identify duplicates in an array
Looks like you are trying to find elements that have duplicates. Here are several ways, pick the one you like:
a.select { |x| a.count(x) > 1 }.uniq
a.sort.each_cons(2).map { |x,y| x if x == y }.compact
a.group_by{|x|x}.values.select{|k|k.size>1}.map(&:first)