Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
查找Ruby数组的模式(简化)__Ruby_Arrays_Hash - Fatal编程技术网

查找Ruby数组的模式(简化)_

查找Ruby数组的模式(简化)_,ruby,arrays,hash,Ruby,Arrays,Hash,我试图找到数组的模式。模式=出现频率最高的元素 我知道#enumerable有很多诀窍,但我的学习还没有做到。我正在做的练习假设我可以在不了解enumerable的情况下解决这个问题 我已经写好了我的游戏计划,但我还停留在第二部分。我不确定是否可以将哈希键与数组进行比较,如果找到,则增加值 def mode(array) # Push array elements to hash. Hash should overwrite dup keys. myhash = {} ar

我试图找到数组的模式。模式=出现频率最高的元素

我知道#enumerable有很多诀窍,但我的学习还没有做到。我正在做的练习假设我可以在不了解enumerable的情况下解决这个问题

我已经写好了我的游戏计划,但我还停留在第二部分。我不确定是否可以将哈希键与数组进行比较,如果找到,则增加值

def mode(array)    
  # Push array elements to hash.  Hash should overwrite dup keys.
  myhash = {}
  array.each do |x|
      myhash[x] = 0
  end

  # compare Hash keys to Array.  When found, push +=1 to hash's value.    

  if myhash[k] == array[x]
    myhash[k] += 1
  end

  # Sort hash by value
  # Grab the highest hash value
  # Return key(s) per the highest hash value
  # rejoice!
end

test = [1, 2, 3, 3, 3, 4, 5, 6, 6, 6]
mode(test) # => 3, 6 (because they each appear 3 times)

在您的方法中,您首先初始化了一个散列,其中包含从数组的唯一值中提取的键,关联的值都设置为零。例如,数组
[1,2,2,3]
将创建散列
{1:0,2:0,3:0}

在此之后,您计划通过将散列中关联键的值为每个实例增加1来计算数组中每个值的实例数。因此,在找到数组中的编号
1
后,散列将如下所示:
{1:1,2:0,3:0}
。您显然需要对数组中的每个值执行此操作,因此,考虑到您的方法和当前的理解水平,我建议再次循环数组:

array.each do |x|
  myhash[x] += 1
end
如您所见,我们不需要检查
myhash[k]==array[x]
,因为我们已经为数组中的每个数字创建了一个key:value对

然而,虽然这种方法可以工作,但效率不是很高:我们必须在数组中循环两次。第一次是将所有键:值对初始化为某个默认值(在本例中为零),第二次是计算每个数字的频率

由于每个键的默认值将为零,我们可以通过使用不同的哈希构造函数来消除初始化默认值的需要。
myhash={}
如果访问不存在的键,将返回
nil
,但是
myhash=hash。如果访问不存在的键,则新(0)
将返回
0
(请注意,如果需要,您可以提供任何其他值或变量)

通过提供默认值零,我们可以完全摆脱第一个循环。当第二个循环发现一个不存在的键时,它将使用提供的默认值并自动初始化它。

您可以创建一个:

然后增加特定事件:

myhash["foo"] += 1
myhash["bar"] += 7
myhash["bar"] += 3
p myhash    # {"foo"=>1, "bar"=>10}
有了这样的理解,如果您替换初始哈希声明,然后在
数组中进行递增,那么每个
迭代器实际上都完成了

myhash.sort_by{|key,value| value}[-1] 

给出已排序的哈希值集中的最后一个条目,这应该是您的模式。请注意,可能有多种模式,因此您可以在值部分保持不变的情况下向后迭代以确定所有模式。

有很多种方法可以做到这一点。以下是一些方法

def mode(array)
    array.group_by{ |e| e }.group_by{ |k, v| v.size }.max.pop.map{ |e| e.shift }
end
#1

array = [3,1,4,5,4,3]
a = array.uniq                   #=> [3, 1, 4, 5]
         .map {|e| [e, array.count(e)]}
                                 #=> [[3, 2], [1, 1], [4, 2], [5, 1]]
         .sort_by {|_,cnt| -cnt} #=> [[3, 2], [4, 2], [1, 1], [5, 1]]
a.take_while {|_,cnt| cnt == a.first.last}
                                 #=> [[3, 2], [4, 2]]
 .map(&:first)                   #=> [3, 4]
#2

array.sort                       #=> [1, 3, 3, 4, 4, 5]
     .chunk {|e| e}
       #<Enumerator: #<Enumerator::Generator:0x000001021820b0>:each>
     .map { |e,a| [e, a.size] }  #=> [[1, 1], [3, 2], [4, 2], [5, 1]]
     .sort_by { |_,cnt| -cnt }   #=> [[4, 2], [3, 2], [1, 1], [5, 1]]
     .chunk(&:last)
       #<Enumerator: #<Enumerator::Generator:0x00000103037e70>:each>
     .first                      #=> [2, [[4, 2], [3, 2]]]
     .last                       #=> [[4, 2], [3, 2]]
     .map(&:first)               #=> [4, 3]
#4

a = array.group_by { |e| e }     #=> {3=>[3, 3], 1=>[1], 4=>[4, 4], 5=>[5]}
         .map {|e,ees| [e,ees.size]}
                                 #=> [[3, 2], [1, 1], [4, 2], [5, 1]]
max = a.max_by(&:last)           #=> [3, 2]
       .last                     #=> 2
a.select {|_,cnt| cnt == max}.map(&:first)
                                 #=> [3, 4]

使用
simple_stats
gem:

test = [1, 2, 3, 3, 3, 4, 5, 6, 6, 6]
test.modes #=> [3, 6]

如果是未排序的数组,我们可以按降序对数组进行排序

array = array.sort!
然后使用排序数组创建哈希默认值0,数组的每个元素作为键,出现次数作为值

hash = Hash.new(0)
array.each {|i| hash[i] +=1 }
如果哈希按值的降序排序(出现次数),则mode将是第一个元素


请定义“模式”,包括数组是
[1,1,2,2]
的情况。另外,您的示例有一个有序数组。数组是从最小到最大排序的吗?请在提问时尽量完整和精确。我很抱歉。通过“模式”,我正在查找元素出现频率最高的。在本例中,答案为3和6(每个出现3次)。你提出了一个很好的观点-我可能还需要建立一个.sort来处理任何非有序数组。CJ,在澄清时,最好编辑你的问题,而不是在注释中解释,因为不是每个人都阅读后者。无论何时编辑,你都不应该更改以前的内容。相反,请确定编辑。一些SO成员写道:“编辑:…”.不必在你问题的结尾。
array = array.sort!
hash = Hash.new(0)
array.each {|i| hash[i] +=1 }
mode = hash.sort_by{|key, value| -value}.first[0]