user3540466
user3540466

Reputation: 303

combine elements of an array in pairs ruby

I have a array that looks like this:

booklist = [000A,000B,000C]

I would like to combine all elements in pairs so that this is the output array:

combinedbooks = [000A|000B, 000A|000C, 000B|000C]

what I have done is the following:

combinedbooks= Array.new
    for i in 0..booklist.length
        for j in i+1..booklist.length                  
            combinedbooks.push(booklist(i) + "|" + booklist(j))
        end
    end

Its not working and I have no idea why

Upvotes: 2

Views: 2733

Answers (6)

Darkmouse
Darkmouse

Reputation: 1939

You could try something like this.

booklist = ['000A', '000B', '000C']
pairs = booklist.combination(2).to_a
pairs.map!{|a,b|"#{a}|#{b}"}

Upvotes: 0

Anthony
Anthony

Reputation: 15957

An alternative to your nested for loops is to use #combination:

[25] pry(main)> booklist
=> ["000A", "000B", "000C"]
[26] pry(main)> booklist.combination(2).map { |i| i.join("|") }
=> ["000A|000B", "000A|000C", "000B|000C"]

Upvotes: 4

Ajedi32
Ajedi32

Reputation: 48348

There are actually two problems with your code as written. The first is that specific elements of arrays should be referenced with brackets [], not parentheses (). The second is that, since Arrays in Ruby are zero-indexed, list[list.length] does not exist (list[list.length-1] is the last element in the array). If we fix these two problems, you end up with:

booklist = ["000A", "000B", "000C"]

combinedbooks = Array.new
for i in 0..booklist.length-1
  for j in i+1..booklist.length-1
    combinedbooks.push(booklist[i] + "|" + booklist[j])
  end
end

Which works as you intended.

Ruby is a pretty powerful language though, so there's actually a much simpler way of doing what you want using a combination of the combination, map, and join methods on Array:

booklist = ["000A", "000B", "000C"]
combinedbooks = booklist.combination(2).map{|combination| combination.join("|")}

Upvotes: 3

davegson
davegson

Reputation: 8331

Here's another solution with an until loop

booklist = ["000A","000B","000C"]

# duplicate the array
booklist_dup = booklist

result_array = []

until booklist_dup.empty?
  # takes the first element out of the array
  first_el = booklist_dup.shift

  # create a combination with each element of the remaining array
  booklist.each{ |el| result_array << first_el + "|" + el}
end

# => ["000A|000B", "000A|000C", "000B|000C"]

Upvotes: 0

floum
floum

Reputation: 1159

Use Array#combination for that kind of behavior :

booklist = ['000A', '000B', '000C']
booklist.combination(2).map { |pair| pair.join('|') }

Upvotes: 0

usha
usha

Reputation: 29349

booklist = ['000A', '000B', '000C']
joined_booklist = []
booklist.each_with_index do |book, i|
   next if i == (booklist.length - 1)
  ((i+1)..(booklist.length-1)).each do |j|
     joined_booklist << book + "|" + booklist[j]
  end
end

Upvotes: 0

Related Questions