Arnis Lapsa
Arnis Lapsa

Reputation: 47677

Pairing array elements in ruby

Let's say i have an array called teams.
I want to plan matches for every team with every other team.

This is almost what i want except that same matches are added twice:

teams.each do |red_team|
  teams.each do |blue_team|
    if red_team != blue_team
      @planned_matches << Match.new(red_team, blue_team)
    end
  end
end

How to do that?

Upvotes: 0

Views: 662

Answers (3)

FMc
FMc

Reputation: 42421

In Ruby 1.8.7+ you can use Array#combination:

teams = %w(A B C D)
matches = teams.combination(2).to_a

In 1.8.6, you can use Facets to do the same:

require 'facets/array/combination'
# Same code as above.

Upvotes: 8

Romain Deveaud
Romain Deveaud

Reputation: 824

In your class Match, assuming internal attributes are red and blue

class Match
#...
  def ==(anOther)
    red == anOther.blue and anOther.red == blue
  end
#...
end

and the loop :

teams.each do |red_team|
  teams.each do |blue_team|
    if red_team != blue_team
      new_match = Match.new(red_team, blue_team)
      planned_matches << new_match if !planned_matches.include?(new_match)
    end
  end
end

Explanation :

The include? function of Array uses the == methods, so you just have to override it and giving it the behaviour you want for your Matches.

Upvotes: 0

Salil
Salil

Reputation: 47542

check if it works

for i in 0..teams.length-1
  if i != teams.last
    for j in (i+1)..teams.length-1
      @planned_matches << Match.new(teams[i], teams[j])
    end
  end
end

EXAMPLE

teams = ['GERMANY', 'NETHERLAND', 'PARAGUAY', 'ARGENTINA']
for i in 0..teams.length-1
  if i != teams.last
    for j in (i+1)..teams.length-1
      puts " #{teams[i]}  Vs  #{teams[j]}"
    end
  end
end

O/P

 GERMANY  Vs  NETHERLAND
 GERMANY  Vs  PARAGUAY
 GERMANY  Vs  ARGENTINA
 NETHERLAND  Vs  PARAGUAY
 NETHERLAND  Vs  ARGENTINA
 PARAGUAY  Vs  ARGENTINA

Upvotes: 2

Related Questions