我已经读过<<<<<<<< + =。但我想我可能无法理解这些差异,因为我的预期代码不会输出我想要实现的内容。
回应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]不同,对我来说,我在这个特定情况下的逻辑是正确的。
答案 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变量只存储对象的引用,而不是对象本身。这里的简化代码与您的代码完全相同,并且具有相同的问题。我告诉它在循环的每次迭代中打印temp
和words_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"]