Ruby 数组#删除#或数组#切片!?以及如何查找实现
我正在清理大数据文件(+1MM逗号分隔行)。示例行可能如下所示:Ruby 数组#删除#或数组#切片!?以及如何查找实现,ruby,arrays,Ruby,Arrays,我正在清理大数据文件(+1MM逗号分隔行)。示例行可能如下所示: @row = "123456789,11122,CustomerName,2014-01-31,2014-02-01,RemoveThisEntry,R,SKUInfo,05-MAR-14 05:50:24,SourceID,RemoveThisEntryToo,TransactionalID" @row = "123456789,11122,CustomerName,2014-01-31,2014-02-01,R,SKUInf
@row = "123456789,11122,CustomerName,2014-01-31,2014-02-01,RemoveThisEntry,R,SKUInfo,05-MAR-14 05:50:24,SourceID,RemoveThisEntryToo,TransactionalID"
@row = "123456789,11122,CustomerName,2014-01-31,2014-02-01,R,SKUInfo,05-MAR-14 05:50:24,SourceID,TransactionalID"
必须从中删除某些列,然后该行应如下所示:
@row = "123456789,11122,CustomerName,2014-01-31,2014-02-01,RemoveThisEntry,R,SKUInfo,05-MAR-14 05:50:24,SourceID,RemoveThisEntryToo,TransactionalID"
@row = "123456789,11122,CustomerName,2014-01-31,2014-02-01,R,SKUInfo,05-MAR-14 05:50:24,SourceID,TransactionalID"
问题1:如果我将一行数据转换为数组
,删除元素时首选哪种方法:或者?我想知道哪一个更为惯用。性能是这里的一个考虑因素,我在一台Windows机器上
def remove_bad_columns
ary = @row.split(",")
ary.delete_at(10)
ary.delete_at(5)
@row = ary.join(",")
end
问题2:我想知道这些方法中是否有一种是用另一种实现的。我怎样才能看到这些方法是如何在ruby中构建的?(例如,如何使用
每个来实现。在性能上并没有什么差别。我更喜欢在
处删除,因为这样读起来更好
require 'benchmark'
def array
"123456789,11122,CustomerName,2014-01-31,2014-02-01,RemoveThisEntry,R,SKUInfo,05-MAR-14 05:50:24,SourceID,RemoveThisEntryToo,TransactionalID"
end
def delete_at
ary = array.dup.split(",")
ary.delete_at(10)
ary.delete_at(5)
@row = ary.join(",")
end
def slice!
ary = array.dup.split(",")
ary.slice!(10)
ary.slice!(5)
@row = ary.join(",")
end
require 'benchmark'
n = 1_000_000
Benchmark.bmbm(15) do |x|
x.report("delete_at :") { n.times do; delete_at; end }
x.report("slice! :") { n.times do; slice! ; end }
end
# Rehearsal ---------------------------------------------------
# delete_at : 4.560000 0.000000 4.560000 ( 4.566496)
# slice! : 4.580000 0.010000 4.590000 ( 4.576767)
# ------------------------------------------ total: 9.150000sec
#
# user system total real
# delete_at : 4.500000 0.000000 4.500000 ( 4.505638)
# slice! : 4.600000 0.000000 4.600000 ( 4.613447)
我建议您使用而不是删除或切片代码>:
def remove_vals(str, *indices)
ary = str.split(",")
v = (0...ary.size).to_a - indices
ary.values_at(*v).join(",")
end
@row = "123456789,11122,CustomerName,2014-01-31,2014-02-01,RemoveThisEntry," +
"R,SKUInfo,05-MAR-14 05:50:24,SourceID,RemoveThisEntryToo,TransactionalID"
@row = remove_vals(@row, 5, 10)
#=> "123456789,11122,CustomerName,2014-01-31,2014-02-01,R,SKUInfo," +
# "05-MAR-14 05:50:24,SourceID,TransactionalID"
Array#values_at
与其他两种方法相比具有优势,您不必担心删除元素的顺序
这种方法的效率与其他两种方法没有显著差异。如果@spickermann希望将其添加到基准测试中,他可以使用以下方法:
def values_at
ary = array.split(",")
v = (0...ary.size).to_a - [5,10]
@row = ary.values_at(*v).join(",")
end
处理CSV数据时应该使用Ruby。如果速度很重要,命令行工具通常会更快:cut-d“,“-f1-5,7-10,12 largedatafile.csv
性能在这里很重要,因为查看一年(或更长)的观察结果时,文件可能包含+6MM行。(我应该在问题中提到这一点。)我在第一次使用时也尝试过使用CSV
库(因为你肯定是对的),但是脚本一直被数据中令人讨厌的工件绊倒——在通过字符串操作进行了这么多Santize之后,我想我会一直坚持使用字符串。我没有考虑过像cut
这样的*nix实用程序,现在正在下载cygwin
来尝试一下。谢谢您可以随时翻阅MRI Ruby代码。它是开放的,它将允许您查看如何在较低级别上实现。准备好阅读MRI Ruby中的C:),数组切片
由函数实现,在这种情况下,您只传递一个要删除的索引rb_ary_delete_at
是最终实现Array#delete_at
的函数,通过该函数,只需将参数从Ruby对象转换为C“long”。如果您的列包含嵌入逗号,如果您尝试使用像split(',')
这样简单的方法进行拆分,您将很快陷入困境。CSV将处理简单代码无法处理的条件。我在
中选择了delete\u以提高可读性,哈哈。谢谢你也做了基准测试-你认为它们的相似性意味着一个是根据另一个来实现的吗?在
上没有方法deleted\u。这是一个非常棒的策略,在一个小测试中像gangbusters一样工作-谢谢!正在使用的值\u已添加到我的待办事项列表中。。。