ruby操作符与铲子混淆(<<<<<&)和= =,Concating数组

时间:2016-06-24 17:18:28

标签: ruby operators concatenation

我已经读过<<<<<<<< + =。但我想我可能无法理解这些差异,因为我的预期代码不会输出我想要实现的内容。

回应Ruby differences between += and << to concatenate a string

我想将“猫”解读为其字母/单词的数组 =&GT; [“c”,“ca”,“cat”,“a”,“at”,“t”]

def helper(word)
words_array = []
idx = 0
while idx < word.length 
    j = idx  
    temp = ""
    while j < word.length
        **temp << word[j]**
        words_array << temp unless words_array.include?(temp) 
    j += 1 
    end
    idx += 1 
end 
p words_array
end
helper("cat")

我不明白为什么 温度&lt;&lt;字[j]的 与temp + = word [j]不同,对我来说,我在这个特定情况下的逻辑是正确的。

3 个答案:

答案 0 :(得分:3)

一个不同之处在于,因为<<适用,所以它比+=快一些。以下代码

require 'benchmark'

a = ''
b= ''

puts Benchmark.measure {
  100000.times { a << 'test' }
}

puts Benchmark.measure {
  100000.times { b += 'test' }
}

产量

0.000000   0.000000   0.000000 (  0.004653)
0.060000   0.060000   0.120000 (  0.108534)

<强>更新

我最初误解了这个问题。这是最近发生的事情。 Ruby变量只存储对象的引用,而不是对象本身。这里的简化代码与您的代码完全相同,并且具有相同的问题。我告诉它在循环的每次迭代中打印tempwords_array

def helper(word)
  words_array = []

  word.length.times do |i|
    temp = ''
    (i...word.length).each do |j|
      temp << word[j]
      puts "temp:\t#{temp}"
      words_array << temp unless words_array.include?(temp)
      puts "words:\t#{words_array}"
    end
  end

  words_array
end

p helper("cat")

以下是它的印刷品:

temp:   c
words:  ["c"]
temp:   ca
words:  ["ca"]
temp:   cat
words:  ["cat"]
temp:   a
words:  ["cat", "a"]
temp:   at
words:  ["cat", "at"]
temp:   t
words:  ["cat", "at", "t"]
["cat", "at", "t"]

正如您所看到的,在内部循环的第一次迭代之后,ruby只是替换words_array的最后一个元素。这是因为words_array包含对temp引用的字符串对象的引用,<<修改该对象而不是创建新对象。

在外部循环temp的每次迭代中都设置为一个新对象,并且该新对象被附加到words_array,因此它不会替换先前的元素。

+=构造在内循环的每次迭代中向temp返回一个新对象,这就是它的行为符合预期的原因。

答案 1 :(得分:2)

temp << word[j]修改temp inplace;

temp += word[j]temp = temp + word[j]的简写,会创建另一个对象并将其分配给temp变量。

顺便说一句:

input = 'cat'.split('')
(1..input.length).each_with_object([]) do |i, memo|
  memo << input.each_cons(i).to_a
end.flatten(1).map(&:join)
#⇒ [
#    [0] "c",
#    [1] "a",
#    [2] "t",
#    [3] "ca",
#    [4] "at",
#    [5] "cat"
#  ]

答案 2 :(得分:2)

# this code might be easier to follow
word = "cat"

def helper(word)
  letter_array = []
  copy_cat = word
  word.length.times do
    starts = 0
    ends = 0
    loop do
      letter_array << copy_cat[starts..ends]
      ends += 1
      break if ends == copy_cat.length
    end
    copy_cat.delete!(word[0])
  end
  letter_array
end

p helper(word) # returns ["c", "ca", "cat", "a", "at", "t"]