0

I have the following array.

@arr = ["A:c,b,a", "B:a,b,d", "C:a,c,b", "D:d,a,c", "a:A,C,D", "b:D,A,B", "c:B,A,C", "d:D,C,A"] 

I want to create an array with the combination of the letter before : and after :.

Output

["Ac,Ab,Aa", "Ba,Bb,Bd", "Ca,Cc,Cb", "Dd,Da,Dc", "aA,aC,aD", "bD,bA,bB", "cB,cA,cC", "dD,dC,dA"]

I have tried the following but it gives an error.

@arr.each { |item| name, choices =item.split(':')
            @names<<name
            @choices<<choices.strip
}
@combi = @name.product(@choices)

I appreciate any inputs. I thank you in advance.

=========

Full code

soshisoai.rb

class Soshisoai

  attr_reader :names, :choices, :arr, :combi

  def initialize 
    @arr=[]
    @names=[]
    @choices=[]
    file = File.new('soshisoai.txt', "r")
    file.each_line{|line| @arr<< line.strip }
    @arr.each { |item| name, choices =item.split(':')
                @names<<name
                @choices<<choices.strip
    }
    @combi = @name.product(@choices)

  end

end

soshisoai_spec.rb

require './spec_helper'
require './soshisoai.rb'

describe Soshisoai do

  specify{ expect(Soshisoai.new().arr).to eq ["A:c,b,a", "B:a,b,d", "C:a,c,b", "D:d,a,c", "a:A,C,D", "b:D,A,B", "c:B,A,C", "d:D,C,A"] }    
  specify{ expect(Soshisoai.new().names).to eq ["A", "B", "C", "D", "a", "b", "c", "d"] }
  specify{ expect(Soshisoai.new().choices).to eq ["c,b,a", "a,b,d", "a,c,b", "d,a,c", "A,C,D", "D,A,B", "B,A,C", "D,C,A"] }
  specify{ expect(Soshisoai.new().combi).to eq ["Ac,Ab,Aa", "Ba,Bb,Bd", "Ca,Cc,Cb", "Dd,Da,Dc", "aA,aC,aD", "bD,bA,bB", "cB,cA,cC", "dD,dC,dA"] }

end

soshisoai.txt

A:c,b,a
B:a,b,d
C:a,c,b
D:d,a,c
a:A,C,D
b:D,A,B
c:B,A,C
d:D,C,A
1
  • What is the error that you get? Commented Apr 6, 2014 at 3:38

3 Answers 3

3
@arr.map do |e|
  before, afters = e.split(":")
  afters.split(",").map{|after| "#{before}#{after}"}.join(",")
end
# => ["Ac,Ab,Aa", "Ba,Bb,Bd", "Ca,Cc,Cb", "Dd,Da,Dc", "aA,aC,aD", "bD,bA,bB", "cB,cA,cC", "dD,dC,dA"]
Sign up to request clarification or add additional context in comments.

Comments

1

Yes, you can use Array#product:

Code

@arr.map { |str| lead, rest = str.split(':');
  [lead].product(rest.split(',')).map(&:join).join(',') } 

Explanation

@arr = ["A:c,b,a", "B:a,b,d", "C:a,c,b", "D:d,a,c",
        "a:A,C,D", "b:D,A,B", "c:B,A,C", "d:D,C,A"]

map first passes "A:c,b,a" to the block and this is assigned to the block variable:

str = "A:c,b,a"
lead, rest = str.split(':')
  #=> ["A", "c,b,a"]

so lead => "A" and rest => "c,b,a".

rest.split(',')
  #=> ["c", "b", "a"]

so

a = ["A"].product(["c", "b", "a"])
  #=> [["A", "c"], ["A", "b"], ["A", "a"]]

b = a.map(&:join)
  #=> ["Ac", "Ab", "Aa"]  

b.join(',')
  #=> "Ac,Ab,Aa"

After performing similiar calculations for each of the other elements of @arr, we obtain:

@arr.map { |str| lead, rest = str.split(':');
  [lead].product(rest.split(',')).map(&:join).join(',') } 
  #=> ["Ac,Ab,Aa", "Ba,Bb,Bd", "Ca,Cc,Cb", "Dd,Da,Dc",
  #    "aA,aC,aD", "bD,bA,bB", "cB,cA,cC", "dD,dC,dA"]

Comments

0
@arr.each_with_object([]){|e, o| lhsStr, rhsStr = e.split(":");
o << rhsStr.split(",").map{|c| lhsStr + c}.join(",")}

#=> ["Ac,Ab,Aa", "Ba,Bb,Bd", "Ca,Cc,Cb", "Dd,Da,Dc",
     "aA,aC,aD", "bD,bA,bB", "cB,cA,cC", "dD,dC,dA"]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.