Rails 3 - Remove items belonging to array B from array A - ruby

I'm starting to play with arrays, but i'm stuck with something that seems yet very simple...
I'm trying to remove x elements belonging to one array from another array.
I've looked at this but .... blocked :
Deleting items from an array requires multiple passes to remove them all
a = ["1","2","3","4","5","6"]
b = ["1","3"]
c = a.reject { |i| i =~ /b/ }
Well, i'm a bit lot here, thanks!

a = ["1","2","3","4","5","6"]
b = ["1","3"]
c = a - b
same as
c = a.reject{ |e| b.include? e }

If you want to modify an existing array by removing elements in another array you can use minus equals.
a = [1, 2, 3, 1, 4]
b = [1, 4]
a -= b
a
=> [2, 3]
Also keep in mind that subtracting an array of elements from another array will remove all occurrences of those elements not just the first occurrence.

Related

Adding unparallel elements between two arrays

I have a pair of arrays,
array_1 = [1,2,3,4,5]
array_2 = [10,9,8,7,6]
and I'm trying to subtract the nth element of one array from the (n-1)-th element of the second array, starting with the n-th element, yielding an array of:
[9-1, 8-2, 7-3, 6-4] = [8, 6, 4, 2]
I wrote it in a procedural fashion:
array_1.pop
array_2.shift
[array_2,array_1].transpose.map { |a,b| a-b }
but I do not wish to alter the arrays. Is there a method or another way to go about this?
Another way:
enum1 = array_1.to_enum
enum2 = array_2.to_enum
enum2.next
arr = []
loop do
arr << enum2.next - enum1.next
end
arr
#=> [8, 6, 4, 2]
Use the non-destructive drop for the receiver, and zip, which will stop when the receiver runs out of an element even if the argument has more.
array_2.drop(1).zip(array_1).map{|a, b| a - b}
I think you may be overthinking it a bit; as long as both arrays are the same length, you can just iterate over the indices you care about, and reference the other array by index - offset.
array_1 = [1,2,3,4,5]
array_2 = [10,9,8,7,6]
n = 1
(n...array_1.length).map {|i| array_2[i] - array_1[i - 1] }
You can set n to whatever number you like and compute from that point onwards, so even if the arrays were tremendously large, you don't have to generate any intermediate arrays, and you don't have to perform any unnecessary work.

cycle through array using index

I have an array
arr = [1,2,3,4,5]
and I'm wondering if there is a way to cycle through it so something like:
i = 2
arr[3+n]
would return 1, rather than nil
Is that possible using the index, or even with next?
It's called cycle:
c = [1,2,3,4,5].cycle
10.times{p c.next}
Perform a modulo on the index using the array size:
arr = [1, 2, 3, 4, 5]
arr[5 % arr.size] #=> 1

How to find which array element is not present in another

Here is the scenario
a = [1,2,3]
b = [2,5,6]
I would like to find out which elements of b are not present in a. I could use include? to check which ones are. But I am looking for something entirely opposite here.
> a - b
=> [1, 3]
> b - a
=> [5, 6]
(I can't quite tell which way you want to go.)
a = [1,2,3]
b = [2,5,6]
b - a #=> [5, 6]

Ruby: Multiply all elements of an array

Let's say I have an array A = [1, 2, 3, 4, 5]
how can I multiply all elements with ruby and get the result? 1*2*3*4*5 = 120
and what if there is an element 0 ? How can I ignore this element?
This is the textbook case for inject (also called reduce)
[1, 2, 3, 4, 5].inject(:*)
As suggested below, to avoid a zero,
[1, 2, 3, 4, 5].reject(&:zero?).inject(:*)
There is also another way to calculate this factorial!
Should you want to, you can define whatever your last number is as n.
In this case, n=5.
From there, it would go something like this:
(1..num).inject(:*)
This will give you 120. Also, .reduce() works the same way.
Well, this is a dummy way but it works :)
A = [1, 2, 3, 4, 5]
result = 1
A.each do |i|
if i!= 0
result = result*i
else
result
end
end
puts result
If you want to understand your code later on, use this: Assume A = 5, I used n instead of A
n = 5
n.times {|x| unless x == 0; n = n * x; ++x; end}
p n
To carry it forward, you would:
A = [1,2,3,4,5]
arb = A.first
a = A.count
a.times {|x| arb = arb * A[x]; ++x}
p arb

Ruby - list minus

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)

Resources