【问题标题】:ruby operator confusion with shovel (<<) and += , Concating arraysruby 运算符与铲子 (<<) 和 += 混淆,连接数组
【发布时间】:2016-10-27 09:32:52
【问题描述】:

我已经阅读了

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

我想将“Cat”解读为一组字母/单词 => [“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")

我不明白为什么 临时

【问题讨论】:

    标签: ruby operators concatenation


    【解决方案1】:

    一个区别是,因为&lt;&lt; 可以正常工作,所以它比+= 快一些。以下代码

    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 所引用的字符串对象的引用,而&lt;&lt; 会修改该对象而不是创建一个新对象。

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

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

    【讨论】:

    • 你不是在比较完全一样的东西吗?
    • 感谢@sagarpandya82。我修好了。
    • 我同意使用 shovel 方法更快,但我想知道在我的具体情况下为什么 shovel 与 += 不同,因为逻辑对我来说是有道理的
    • 我明白了。我已经更新了我的答案来解决你的问题。
    【解决方案2】:

    temp &lt;&lt; word[j] 就地修改temp

    ✓ 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"
    #  ]
    

    【讨论】:

      【解决方案3】:
      # 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"]
      

      【讨论】:

        猜你喜欢
        • 2012-09-15
        • 1970-01-01
        • 2018-04-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-29
        • 2020-10-25
        • 1970-01-01
        相关资源
        最近更新 更多