如何根据第三个数组的顺序合并Ruby中两个数组的项?
我有三个数组 我的主列表包含在数据库中验证的不同实体的组合:如何根据第三个数组的顺序合并Ruby中两个数组的项?,ruby,arrays,sorting,Ruby,Arrays,Sorting,我有三个数组 我的主列表包含在数据库中验证的不同实体的组合: ab = ["a:555", "b:222", "a:333", "b:777", "a:777", "a:999", "b:111"] 我又有两个a和b实体数组,它们是分开的,但有序的(有些缺失): 在数组c中合并a和b的有效方法是什么?在ab中保留项目存在的顺序?我的预期结果是: c = ["a:555", "b:222", "a:777", "a:999", "b:111"] 我是一个红宝石新手,我想到的一切都非常丑陋 编
ab = ["a:555", "b:222", "a:333", "b:777", "a:777", "a:999", "b:111"]
我又有两个a
和b
实体数组,它们是分开的,但有序的(有些缺失):
在数组c
中合并a
和b
的有效方法是什么?在ab
中保留项目存在的顺序?我的预期结果是:
c = ["a:555", "b:222", "a:777", "a:999", "b:111"]
我是一个红宝石新手,我想到的一切都非常丑陋
编辑: 我知道这很重要,而且会让人困惑,但是
a
和b
是复杂对象(AR),它们表示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
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.每个{|项目|
零件=项目。拆分(“:”)
如果零件[0]=“a”
如果一个[0][:id].to_s()==部分[1]
c如果值的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的索引预计算为哈希(一个O(N)操作,允许在排序方式中查找O(1):
如果值的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的索引预计算为哈希(一个O(N)操作,允许在排序方式中查找O(1):
以下是如何将一个数组按与另一个数组相同的顺序排序的基础。从两个数组开始:
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_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"]]
在合并和排序之前,将数组放入所需的格式是一个问题。一旦有了这些数组,并且它们的元素数相等,这是一个非常简单的模式。以下是如何将数组按与另一个数组相同的顺序排序的基础。从两个数组开始:
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_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"]]
在合并和排序之前,将数组转换为所需的形式是一个问题。一旦有了这些数组,并且它们的元素数相等,这是一个非常简单的模式。对不起,我没有理解。你想出了什么?是的,这个问题很混乱。我会在一分钟内添加代码。@Veseliq这里的重点是比较ab
和a
和b
中的对象。有用的是知道如何从对象中获取ab
中的字符串,我假设您不使用变量名a
和b
来生成这些字符串。是否有可能在a
和b
或所有变量中保持相同的值告诉我它们将有唯一的值?抱歉,我没听懂。你想出了什么?是的,这个问题令人困惑。我会在一分钟内添加我的代码。@Veseliq这里的重点是将ab
中的字符串与a
和b
中的对象进行比较。了解如何从您那里获得ab
中的字符串非常有用你的对象,我想你不会使用变量名a
和b
来生成那些字符串。有没有可能在a
和b
中都有相同的值,或者它们一直都有唯一的值?最后一行,太棒了。如果可能的话,我会重复两次。@Priti你的问题把我弄糊涂了。sort\u by
I它比选择任何答案更简单、更有效。运行排序的复杂性为O(N lnN);选择任何答案的复杂性为O(N^2)@dbenhur我不想卷入任何争论,你知道。但我想知道的是,为什么你使用了sort\u by
。因为OP的输出似乎不需要排序。@Priti OP的问题是关于根据ab
中键的顺序生成一个顺序。sort\u by允许一个更快的算法——在重新访问我的解决方案时我发现使用ab.index忽略了运行时成本;所以我更新了一个子句来消除这一点。最后一行,太棒了。如果可以的话,我会重复两次。@Priti您的问题让我困惑。sort\u by
比您选择的any?
答案更简单、更有效。sort\u by的运行复杂性是O(N lnN);您对任何?的选择为O(N^2)@dbenhur我不想卷入任何争论,你知道。但我想知道的是,为什么你使用了sort\u by
。因为OP的输出似乎不需要排序。@Priti OP的问题是关于根据ab
中键的顺序生成一个顺序。sort\u by允许一个更快的算法——在重新访问我的解决方案时我发现使用ab.index忽略了运行时成本;所以我更新了一个子句来消除这一点。