0

我有三个数组。

我的主列表包含在数据库中验证的不同实体的组合:

ab = ["a:555", "b:222", "a:333", "b:777", "a:777", "a:999", "b:111"]

我还有两个数组ab实体分开,但有序(有些缺失):

# notice that some of the items from the initial list are missing, but the order is preserved!
a = [{id}, "a:777", "a:999"]
b = ["b:222", "b:111"]

什么是合并ab在数组中保留项目存在c顺序的有效方法?ab我对该程序的预期结果是:

c = ["a:555", "b:222", "a:777", "a:999", "b:111"]

我是一个 Ruby 新手,我想出的一切都非常丑陋。


编辑:

我确实知道这很重要,并且会令人困惑,但是a并且b是表示ab. 为了澄清我的代码:

ab = ["a:555", "b:222", "a:333", "b:777", "a:777", "a:999", "b:111"]
a = [{:id => 555}, {:id => 777}, {:id => 999}]
b = [{:id => 222}, {:id => 111}]
c = []

ab.each { |item|
parts = item.split(":")
if parts[0] == "a"
  if a[0][:id].to_s() == parts[1]
    c << a.shift()
  end
else
  if b[0][:id].to_s() == parts[1]
    c << b.shift()  
  end
end

}

puts c
4

2 回答 2

3

如果值id在 a 和 b 之间没有区别,则可以这样做

c = (
  a.map { |e| [ "a:#{e[:id]}", e ] } +
  b.map { |e| [ "b:#{e[:id]}", e ] }
).
sort_by { |e| ab.index(e.first) }.
map(&:last)

由于您现在声明它们是不同的,并且对象上有一个方法可以产生您的 ab 键,所以这更简单:

c = (a + b).sort_by { |e| ab.index(e.get_ab_string) }

ab.index是对 ab 的 O(N) 操作,因此它将通常的 NlnN 排序升级为 N^2。要将整个解决方案带回 O(NlnN) 运行时,可以将 ab 的索引预先计算为哈希(允许在 sort_by 中进行 O(1) 查找的 O(N) 操作):

ab_idx = Hash[ ab.map.with_index { |e,i| [e, i] } ]
c = (a + b).sort_by { |e| ab_idx(e.get_ab_string) }
于 2013-05-09T10:37:20.520 回答
0

这是如何将数组排序为与另一个数组相同的顺序的基础。从两个数组开始:

ary_a = %w[one four three two]
ary_b = [1, 4, 3, 2]

合并它们,排序,然后检索我们想要排序的那个:

ary_a.zip(ary_b).sort_by{ |a, b| b }.map(&:first)
=> ["one", "two", "three", "four"]

如果我们想颠倒顺序:

ary_a.zip(ary_b).sort_by{ |a, b| -b }.map(&:first)
=> ["four", "three", "two", "one"]

或者:

ary_a.zip(ary_b).sort_by{ |a, b| b }.map(&:first).reverse
=> ["four", "three", "two", "one"]

如果有三个数组并且两个需要与第三个一起排序:

ary_c = %w[a-one a-four a-three a-two]
ary_a.zip(ary_c).zip(ary_b).sort_by{ |a, b| b }.map(&:first)
=> [["one", "a-one"], ["two", "a-two"], ["three", "a-three"], ["four", "a-four"]]

在合并和排序之前将数组转换为所需的形式是问题所在。一旦你有了这些,并且它们有相同数量的元素,这是一个非常简单的模式。

于 2013-05-09T14:03:53.570 回答