在2个循环内将字符串插入字符串

时间:2012-09-14 05:25:36

标签: ruby string

我循环查看单词列表,并在每个单词的开头插入字母表中的每个字母,并使用以下代码:

def add_charac_front
  ("a".."z").each do |letter|
    @array.each do |list_word|
      list_word.insert(0, letter)
      puts list_word
    end #ends @array loop
  end #ends alphabet loop
end #ends method 

.insert正在更改@array,以便当我通过@array循环显示字母“b”时,list_word中的第一个@array }不是“Hello”而是“aHello”。

我需要完全相同的行为,但是@array对于我运行的每个字母循环都是相同的数组。我执行此代码时它正常工作:

def add_charac_front
  ("a".."z").each do |letter|
    @array.each do |list_word|
      puts "#{letter}#{list_word}"
    end #ends @array loop
  end #ends alphabet loop
end #ends method

但我最终想在list_word的不同部分插入字母,而不仅仅是前面。

我想我能做到这一点的另一种方式是.split("") list_word,然后.insert(0, letter),然后是.join。但这似乎更麻烦。

我该怎么做?

4 个答案:

答案 0 :(得分:2)

Ruby通过引用传递,而不是通过值传递。这意味着list_word实际上指向@array内的原始单词。

如果您只想使用list_word而不影响原始数组,则需要制作它的丢弃副本,例如:

def add_charac_front
  ("a".."z").each do |letter|
    @array.each do |orig_word|
      list_word = orig_word.dup # duplicates the list_word
      list_word.insert(0, letter)
      puts list_word
    end #ends @array loop
  end #ends alphabet loop
end #ends method 

答案 1 :(得分:1)

您还可以使用双引号轻松创建一个新字符串,并使用#{varname}创建一个新字符串。

irb> @array = %w(foo bar baz)
=> ["foo", "bar", "baz"]
irb> ("a".."e").inject([]) { |m,c| 
                m.concat(@array.map { |item| "#{c}-#{item}" });
                m }
=> ["a-foo", "a-bar", "a-baz", "b-foo", "b-bar", "b-baz", "c-foo", "c-bar", "c-baz", "d-foo", "d-bar", "d-baz", "e-foo", "e-bar", "e-baz"]

使用map创建新数组的错误较少,然后当您需要将另一个数组折叠到其中时,请使用inject。如果使用注射感觉不舒服,可以使用map和flatten来实现相同的结果:

irb> ("a".."e").map { |c| @array.map { |item| "#{c}-#{item}" } }
=> [["a-foo", "a-bar", "a-baz"], ["b-foo", "b-bar", "b-baz"], ["c-foo", "c-bar", "c-baz"],     ["d-foo", "d-bar", "d-baz"], ["e-foo", "e-bar", "e-baz"]]
irb> ("a".."e").map { |c| @array.map { |item| "#{c}-#{item}" } }.flatten
=> ["a-foo", "a-bar", "a-baz", "b-foo", "b-bar", "b-baz", "c-foo", "c-bar", "c-baz", "d-foo", "d-bar", "d-baz", "e-foo", "e-bar", "e-baz"]

在Enumerables上使用链式操作可以轻松检查执行中每个点的状态。然后当你需要打印出来时,你可以追加.each {| x |把x}

如果你这么做了,为什么不安装gem cartesian,这使得获得两个阵列的笛卡尔积很简单,这就是你需要的:

irb> require 'cartesian'
=> true
irb> Cartesian::product(("a".."c"), %w(foo bar baz))
=> [["a", "foo"], ["a", "bar"], ["a", "baz"], ["b", "foo"], ["b", "bar"], ["b", "baz"], ["c",   "foo"], ["c", "bar"], ["c", "baz"]]
irb> Cartesian::product(("a".."c"), %w(foo bar baz)).map { |x| "#{x.first}-#{x.last}" }
=> ["a-foo", "a-bar", "a-baz", "b-foo", "b-bar", "b-baz", "c-foo", "c-bar", "c-baz"]

答案 2 :(得分:0)

如果您认为需要使用insert,则可以创建该字符串的新副本。

def add_charac_front
  ("a".."z").each do |letter|
     @array.each do |list_word|
       t = String.new(list_word).insert(0,letter)
       puts t
     end #ends @array loop
  end #ends alphabet loop
end #ends method 

答案 3 :(得分:0)

不确定我是否遵循了这些要求,但我建议您自己操作数组

# example.rb

@alpha = %w{a b c d e f g h i j k l m n o p q r s t u v w x y z}

def add_charac_front(array)
  return @alpha + array
end

或者上面的代码实际上是将字母插入彼此的前面,所以它相当于反转alpha数组并将其插入前面

@reverse_alpha = alpha.reverse

def add_charac_front(array)
  return @reverse_alpha + array
end

希望这会有所帮助。您也可以使用这样的范围来连接子数组

a2 = %w{b c}
a3 = @alpha[0..4] + a2 + @alpha[5..13]