Arrays Ruby排序以高效的方式使用另一个数组对哈希数组进行排序,因此处理时间是恒定的
我有一些数据需要导出为csv。它目前大约有10000条记录,并将继续增长,因此我希望有一种高效的方法来进行迭代,特别是关于一个接一个地运行几个循环。 我的问题是,是否有一种方法可以避免我在下面描述的许多each循环,如果没有,我是否可以在Ruby的each/map旁边使用其他方法来保持处理时间不变,而不考虑数据大小 例如: 首先,我将循环遍历整个数据,以展平并重命名包含数组值的字段,这样,像issue that hol数组值这样的字段将变成issue_1和issue_1,如果它在数组中仅包含两个项 接下来,我将执行另一个循环以获取哈希数组中的所有唯一键 使用第2步中的唯一键,我将执行另一个循环,使用不同的数组对这些唯一键进行排序,该数组保持键的排列顺序 最后是生成CSV的另一个循环 因此,我每次都使用Ruby的each/map对数据进行了4次迭代,完成此循环的时间将随着数据大小的增加而增加 原始数据如下表所示:Arrays Ruby排序以高效的方式使用另一个数组对哈希数组进行排序,因此处理时间是恒定的,arrays,ruby-on-rails,ruby,sorting,big-o,Arrays,Ruby On Rails,Ruby,Sorting,Big O,我有一些数据需要导出为csv。它目前大约有10000条记录,并将继续增长,因此我希望有一种高效的方法来进行迭代,特别是关于一个接一个地运行几个循环。 我的问题是,是否有一种方法可以避免我在下面描述的许多each循环,如果没有,我是否可以在Ruby的each/map旁边使用其他方法来保持处理时间不变,而不考虑数据大小 例如: 首先,我将循环遍历整个数据,以展平并重命名包含数组值的字段,这样,像issue that hol数组值这样的字段将变成issue_1和issue_1,如果它在数组中仅包含两个
def data
[
{"file"=> ["getty_883231284_200013331818843182490_335833.jpg"], "id" => "60706a8e-882c-45d8-ad5d-ae898b98535f", "date_uploaded" => "2019-12-24", "date_modified" => "2019-12-24", "book_title_1"=>"", "title"=> ["haha"], "edition"=> [""], "issue" => ["nov"], "creator" => ["yes", "some"], "publisher"=> ["Library"], "place_of_publication" => "London, UK"]},
{"file" => ["getty_883231284_200013331818843182490_335833.jpg"], "id" => "60706a8e-882c-45d8-ad5d-ae898b98535f", "date_uploaded" => "2019-12-24", "date_modified"=>"2019-12-24", "book_title"=> [""], "title" => ["try"], "edition"=> [""], "issue"=> ["dec", 'ten'], "creator"=> ["tako", "bell", 'big mac'], "publisher"=> ["Library"], "place_of_publication" => "NY, USA"}]
end
通过展平数组并重命名保存这些数组的键来重新映射日期
def csv_data
@csv_data = [
{"file_1"=>"getty_883231284_200013331818843182490_335833.jpg", "id"=>"60706a8e-882c-45d8-ad5d-ae898b98535f", "date_uploaded"=>"2019-12-24", "date_modified"=>"2019-12-24", "book_title_1"=>"", "title_1"=>"haha", "edition_1"=>"", "issue_1"=>"nov", "creator_1"=>"yes", "creator_2"=>"some", "publisher_1"=>"Library", "place_of_publication_1"=>"London, UK"},
{"file_1"=>"getty_883231284_200013331818843182490_335833.jpg", "id"=>"60706a8e-882c-45d8-ad5d-ae898b98535f", "date_uploaded"=>"2019-12-24", "date_modified"=>"2019-12-24", "book_title_1"=>"", "title_1"=>"try", "edition_1"=>"", "issue_1"=>"dec", "issue_2" => 'ten', "creator_1"=>"tako", "creator_2"=>"bell", 'creator_3' => 'big mac', "publisher_1"=>"Library", "place_of_publication_1"=>"NY, USA"}]
end
对上述数据的标题进行排序
def csv_header
csv_order = ["id", "edition_1", "date_uploaded", "creator_1", "creator_2", "creator_3", "book_title_1", "publisher_1", "file_1", "place_of_publication_1", "journal_title_1", "issue_1", "issue_2", "date_modified"]
headers_object = []
sorted_header = []
all_keys = csv_data.lazy.flat_map(&:keys).force.uniq.compact
#resort using ordering by suffix eg creator_isni_1 comes before creator_isni_2
all_keys = all_keys.sort_by{ |name| [name[/\d+/].to_i, name] }
csv_order.each {|k| all_keys.select {|e| sorted_header << e if e.start_with? k} }
sorted_header.uniq
end
生成csv还涉及更多循环:
def to_csv
data = csv_data
sorted_headers = csv_header(data)
csv = CSV.generate(headers: true) do |csv|
csv << sorted_header
csv_data.lazy.each do |hash|
csv << hash.values_at(*sorted_header)
end
end
end
老实说,我更感兴趣的是看我是否能够在没有进一步描述的情况下找到你想要的逻辑,而不仅仅是编程部分,但当然我也很喜欢,我做了一些Ruby,这是一个很好的复习。由于任务没有明确说明,因此必须通过阅读您的描述、输入数据和代码来提炼任务 我认为您应该做的是将所有内容都保存在非常基本和轻量级的阵列中,并在一大步读取数据的同时完成繁重的工作。 我还假设,如果一个键以一个数字结尾,或者一个值是一个数组,那么您希望它以{key}{n}的形式返回,即使只存在一个值 到目前为止,我提出了注释和 类自定义数据 @密钥数组结构 0:键 1:关联值的最大数量 2:数组是否在提要中找到{key}\n键, 提要中的or值是一个数组 @数据:是一个简单的数组数组 属性存取器:键,:数据 CSV\u订单=%w[ id版本日期\u上传创建者书籍\u标题出版商 文件位置\u出版物期刊\u标题发布日期\u修改 ] def初始化种子 @keys=CSV_ORDER.map{| key |[key,0,false]} @数据=[] feed.do每行| 新_行=[] 对键进行排序,以保持{key}{n}值的正确顺序 row.sort_by{| key,{u124; key}。每个do | key,值| 数组是否为false 如果键=~/\ud+$/ 如果密钥以数字结尾,则提取密钥 记住它是一个输出数组 key,is_array=key[/^.*.\u\d+$/,1],true 终止 如果value.u是a?大堆 如果value是数组,即使键没有以数字结尾, 对于输出,我们记住了这一点 数组=真吗 其他的 值=[值] 终止 查找键的位置(如果存在或为零) key|index=@keys.index{| a | a.first==key} if键索引 如果您可以有_n键和数组值的组合 对于提要中的密钥,您需要在此处更改此部分 考虑所有以前的值,这会增加一些复杂性 如果当前值的数量大于已保存的数量,请替代 @如果@keys[key\u index][1]
,希望它能让我想要的更清楚。非常感谢@wiesion,我已经对答案投了赞成票,并将进行实验。我将等待,看看是否有更多的答案,然后再选择一个。在这种情况下,CSV排序是一项功能要求,不仅是为了美观。如果您知道前面的所有标题,或者不知道的标题是按字母顺序追加的,这是一项简单的调整,只需预先填充@键,但结尾没有数字,我就更新了答案。