如何将数组转为键为元素、值为索引(重复元素对应索引数组)的哈希表?
解决数组转索引哈希(支持重复元素)的问题
嗨,我来帮你搞定这个需求!你当前的代码问题在于,每次遇到重复元素时都会直接覆盖之前的索引值,所以最后只能得到该元素的最后一个索引。要实现「重复元素对应索引数组,非重复元素对应单个索引」的效果,我们可以分两种思路来写:
方法一:逐元素判断处理(直观易懂)
我们可以初始化一个空哈希,然后遍历数组的每个元素和索引,根据当前元素是否已存在于哈希中来做不同处理:
- 如果元素不存在,直接把索引赋值给该键;
- 如果元素已存在,先检查当前值是不是数组(因为第一次存的是单个数字),不是的话就转成数组,再把新索引加进去。
代码示例:
array = [1,3,4,5,6,6,6] hash = {} array.each_with_index do |elem, idx| if hash.key?(elem) # 若当前值不是数组,先转为数组 hash[elem] = [hash[elem]] unless hash[elem].is_a?(Array) hash[elem] << idx else hash[elem] = idx end end puts hash.inspect # 输出:{1=>0, 3=>1, 4=>2, 5=>3, 6=>[4, 5, 6]}
方法二:用Ruby内置方法简化(更优雅)
利用group_by和transform_values可以更简洁地实现需求,先按元素分组收集所有索引,再根据索引数量决定是保留单个值还是数组:
array = [1,3,4,5,6,6,6] hash = array.each_with_index.group_by(&:first).transform_values do |pairs| indices = pairs.map(&:second) indices.size == 1 ? indices.first : indices end puts hash.inspect # 输出:{1=>0, 3=>1, 4=>2, 5=>3, 6=>[4, 5, 6]}
思路解释:
array.each_with_index会把每个元素转成[元素, 索引]的数组;group_by(&:first)按元素值分组,得到每个元素对应的所有[元素, 索引]对;transform_values提取每组里的索引,然后判断索引数组的长度:如果只有1个,就取单个值,否则保留数组。
两种方法都能完美满足你的需求,你可以根据自己的习惯选择~
内容的提问来源于stack exchange,提问作者Rubee
相关产品推荐
相关产品推荐

