为什么数组元素会在块后发生变化?

时间:2015-08-04 14:45:27

标签: ruby

我正在尝试解决this problem

  

给定一个包含多个单词的句子,找到该句子中给定单词的频率。

     

构造一个名为'find_frequency'的方法,它接受两个参数'sentence'和'word',两个参数都是String对象。

     

示例:这个方法,假设'Ruby是世界上最好的语言'和'the',应该返回2(比较应该不区分大小写)。

     

提示:您可以使用方法Array#count来计算给定数组中任何元素的频率。

由于比较应该不区分大小写。我使用这些代码来帮助:

word = "the"
word_set = []
word.size.times do |i|
  word[i] = word[i].upcase
  word_set << word
  word[i] = word[i].downcase
end

每次在upcase方法之后,word确实会更改并添加到word_set,但是当块完成时word_set只包含{{1} }} 有什么问题?

4 个答案:

答案 0 :(得分:2)

  

我仍然对该块代码感到困惑

该块使用TypeScript 1.5.3运行3次。这里发生了什么:

i = 0, 1, 2

这是因为您正在修改完全相同的字符串对象。最后,您的数组包含三次相同的字符串实例。

您可以使用dup创建字符串的副本来避免这种情况,例如:

                               #  word   word_set
word[0] = word[0].upcase       #  'The'  []
word_set << word               #  'The'  ['The']
word[0] = word[0].downcase     #  'the'  ['the']

word[1] = word[1].upcase       #  'tHe'  ['tHe']
word_set << word               #  'tHe'  ['tHe', 'tHe']
word[1] = word[1].downcase     #  'the'  ['the', 'the']

word[2] = word[2].upcase       #  'thE'  ['thE', 'thE']
word_set << word               #  'thE'  ['thE', 'thE', 'thE']
word[2] = word[2].downcase     #  'the'  ['the', 'the', 'the']

请注意,您仍需要将word = "the" word_set = [] word.size.times do |i| new_word = word.dup new_word[i] = new_word[i].upcase word_set << new_word end word_set #=> ["The", "tHe", "thE"] theTHetHEThE添加到数组中。

答案 1 :(得分:1)

您反复向数组添加相同的字符串。在循环结束时,数组将包含相同的字符串n次(其中n是字符串的长度)。因此,您在大写和小写之间来回更改相同的字符串,但它仍然只是一个字符串。

答案 2 :(得分:1)

好吧,word[i] = word[i].upcase存在问题,因为您将其设置为大写和小写,word会随着时间的推移而发生变化。你应该关注的是Array#count方法,它以块作为参数。

以下是它的要点:

def find_frequency sentence, word
  sentence.split(" ").count{|w| w == word }
end

要完成它,请考虑wordsentence的案例敏感度来完成拼图

答案 3 :(得分:0)

你可以这样做:

class Array
  def group_and_count     
    self.map(&:downcase).each_with_object(Hash.new(0)){|k,h|h[k] += 1}
  end
end

然后,当您想要找到给定单词的频率时,您可以说:

> words = 'Here is a a a list OF OF words words WORDS'
> freq = words.split.group_and_count
> freq['a']
=> 3