我有一个对象,其数组如下所示:
some_object = {
some_array: [
{ id: "foo0" },
{ id: "foo1" },
{ id: "foo2" },
{ id: "foo3" },
]
}
我有另一个数组的输入,我想在
中重新排列该数组target_order = [
{ id: "foo0", new_position: 3 },
{ id: "foo3", new_position: 0 },
{ id: "foo1", new_position: 2 },
{ id: "foo2", new_position: 1 }
]
如何使用第二个target_order
数组修改第一个some_object[:some_array]
的顺序?
答案 0 :(得分:1)
我建议您将sort_by
与自定义块一起使用,该块可以找到项目在新数组中的位置。
new_array = some_object[:some_array].sort_by do |item|
order = target_order.detect { |order| order[:id] == item[:id] }
next unless order
order[:new_position]
end
这将返回以下值。
=> [{:id=>"foo2"}, {:id=>"foo1"}, {:id=>"foo0"}, {:id=>"foo3"}]
也许您想给每个项目一个列表中的位置,而不仅仅是对其进行排序。例如
target_order = [
{ id: "foo0", new_position: 0 },
{ id: "foo1", new_position: 2 }
]
会给
=> [{ id: "foo0" }, nil, { id: "foo1" }]
为此,您应该使用each_with_object
而不是sort_by
。
new_array = target_order.each_with_object([]) do |order, memo|
item = some_object[:some_array].detect { |item| item[:id] == order[:id] }
next unless item
memo[order[:new_position]] = item
end
答案 1 :(得分:0)
简单起见,这就是我要做的...
temp_arr = []
target_order.each do |o|
x = some_json_object[:some_array].find { |i| o[:id] == i[:id] }
temp_arr[o[:new_position] - 1] = x
end
some_json_object = {
"some_array": temp_arr
}
答案 2 :(得分:0)
如果some_array
和target_order
元素之间存在一对一的对应关系,也许您可以直接进行分配,例如:
some_object[:some_array] = target_order.sort_by{ |h| h[:new_position] }.map { |h| h.delete_if { |k, _| k == :new_position } }
所以,您最终会得到
some_object #=> {:some_array=>[{:id=>"foo3"}, {:id=>"foo2"}, {:id=>"foo1"}, {:id=>"foo0"}]}
答案 3 :(得分:0)
不需要排序,排序具有O(n * log(n))的时间复杂度。这是一个O(n)解。
from os import system, listdir, path
import codecs
FILE = open('C:\\Users\\Admin\\Desktop\\Test\\Result.txt', 'w')
desktop_dir = path.join('C:\\Users\\Admin\\Desktop\\test\\')
for fn in listdir(desktop_dir):
fn_w_path = path.join(desktop_dir, fn)
if path.isfile(fn_w_path):
with open(fn_w_path, "r") as filee:
for line in filee.readlines():
for word in line.lower().split():
if word in {'James',
'Tim',
'Tom',
'Ian',
'William',
'Dennis',}:
FILE.write(word + "\n")
FILE.close()
import os
import shutil
for root, dirs, files in os.walk("test_dir1", topdown=False):
for name in files:
current_file = os.path.join(root, name)
destination = current_file.replace("test_dir1", "test_dir2")
print("Found file: %s" % current_file)
print("File copy to: %s" % destination)
shutil.copy(current_file, destination)
请注意,这里没有引用{ some_array: target_order.each_with_object([]) { |h,a|
a[h[:new_position]] = h.slice(:id) } }
#=> {:some_array=>[{:id=>"foo3"}, {:id=>"foo2"}, {:id=>"foo1"}, {:id=>"foo0"}]}
。
如果要some_object
进行修改:
some_object
使用Enumerable#sort_by,虽然效率较低,但可以这样写:
some_object[:some_array] = target_order.each_with_object([]) { |h,a|
a[h[:new_position]] = h.slice(:id) }
some_object
#=> {:some_array=>[{:id=>"foo3"}, {:id=>"foo2"}, {:id=>"foo1"}, {:id=>"foo0"}]}