如何使用Ruby根据一个数组对另一个数组进行排序

3pmvbmvn  于 2023-02-18  发布在  Ruby
关注(0)|答案(4)|浏览(212)

有两个数组:

A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
B = [3, 4, 1, 5, 2, 6]

我想对B进行排序,对于B中所有存在于A中的元素,按照数组A中的顺序排序。
所需的排序结果为

B #=> [1, 2, 3, 4, 5, 6]

我已经尽力了

B = B.sort_by { |x| A.index }

但它不起作用。
这个问题与可能的重复问题不同,因为它处理的是相应数组中元素的存在,并且这里不存在哈希。

zbq4xfa0

zbq4xfa01#

它完美地工作:

▶ A = [1,3,2,6,4,5,7,8,9,10]
▶ B = [3,4,1,5,2,6]
▶ B.sort_by &A.method(:index)
#⇒ [1, 3, 2, 6, 4, 5]

如果B中可能存在A中不存在的元素,请使用以下命令:

▶ B.sort_by { |e| A.index(e) || Float::INFINITY }
ws51t4hk

ws51t4hk2#

我将从检查B中的哪些元素存在于A中开始:

B & A

然后排序:

(B & A).sort_by { |e| A.index(e) }
zrfyljdw

zrfyljdw3#

首先考虑B的每个元素都在A中的情况,如问题示例所示:

A = [1,2,3,4,5,6,7,8,9,10]
B = [3,6,1,5,1,2,1,6]

可以编写如下代码,它只需要通过A一次(构造g 1)和通过B一次。

g = A.each_with_object({}) { |n,h| h[n] = 1 }
  #=> {1=>1, 2=>1, 3=>1, 4=>1, 5=>1, 6=>1, 7=>1, 8=>1, 9=>1, 10=>1}
B.each_with_object(g) { |n,h| h[n] += 1 }.flat_map { |k,v| [k]*(v-1) }
  #=> [1, 1, 1, 2, 3, 5, 6, 6]

如果不能保证B的所有元素都在A中,并且任何不在A中的元素都被放置在排序数组的末尾,那么可以稍微改变g的计算。

g = (A + (B-A)).each_with_object({}) { |n,h| h[n] = 1 }

这需要再通过A和B一次。
例如,假设,

A = [2,3,4,6,7,8,9]

并且B不变。那么,

g = (A + (B-A)).each_with_object({}) { |n,h| h[n] = 1 }
  #=> {2=>1, 3=>1, 4=>1, 6=>1, 7=>1, 8=>1, 9=>1, 1=>1, 5=>1}
B.each_with_object(g) { |n,h| h[n] += 1 }.flat_map { |k,v| [k]*(v-1) }
  #=> [2, 3, 6, 6, 1, 1, 1, 5]

这个解决方案展示了Ruby v1.9中对散列属性所做的一个有争议的更改的价值:此后将保证散列保持密钥插入顺序。
1我希望可以写g = A.product([1]).to_h,但是doc Array#to_h不能保证返回的哈希中的键的顺序与A中的顺序相同。

7rfyedvj

7rfyedvj4#

你只是在A.index中缺少了x,所以查询应该是

B = B.sort_by { |x| A.index(x) }

相关问题