Ruby 你能按关键字搜索数组吗?

Ruby 你能按关键字搜索数组吗?,ruby,arrays,hash,Ruby,Arrays,Hash,如何将像[“foo”,1,2,3]这样的数组转换成可以通过关键字“foo”快速搜索的数组 我正在尝试获取csv文件,并根据条件对其进行排序/筛选。例如,给定以下csv和标准: foo,bar,foobar 1,2,3 4,5,6 7,8,9 @criteria = ["foobar", "foo"] 输出应如下(顺序很重要): 我正在使用一个嵌套循环来检查@criteria中的每一项与csv的每一个索引[0] require 'csv' @criteria = ["foobar", "fo

如何将像
[“foo”,1,2,3]
这样的数组转换成可以通过关键字
“foo”
快速搜索的数组

我正在尝试获取csv文件,并根据条件对其进行排序/筛选。例如,给定以下csv和标准:

foo,bar,foobar
1,2,3
4,5,6
7,8,9

@criteria = ["foobar", "foo"]
输出应如下(顺序很重要):

我正在使用一个嵌套循环来检查
@criteria
中的每一项与csv的每一个
索引[0]

require 'csv'

@criteria = ["foobar", "foo"]
@newcsv = []
csv = CSV.read("./foo.csv", { headers: true, return_headers: false })
csv = csv.to_a.transpose
@criteria.each do |n|
  csv.each do |i|
    if i[0] == n
      @newcsv.push(i)
      end
  end
end
@newcsv = @newcsv.transpose
CSV.open("./transpose.csv", "wb") do |lines|
  @newcsv.each { |line| lines << line }
end
需要“csv”
@标准=[“foobar”,“foo”]
@newcsv=[]
csv=csv.read(“./foo.csv”,{headers:true,return\u headers:false})
csv=csv.to_a.转置
@标准。每个都做|
csv.each do|i|
如果i[0]==n
@newcsv.push(一)
结束
结束
结束
@newcsv=@newcsv.transpose
CSV.open(“./transpose.CSV”,“wb”)do |行|

@newcsv.each{| line | linesSo这个答案是由另一个用户发布的后来被删除,因为他或她“讨厌它”,但我认为它至少为原始海报添加了一些有用的信息,所以我在这里重新发布

请注意,对于
n*n
矩阵,我不确定此代码是否具有比
O(n^2)
更快的渐近性能,但原始作者不同意我的观点。至少,我的推理如下:

  • 如果您有一个
    n*n
    矩阵,并且您有
    n-1
    标准,那么创建索引不会在最坏的情况下采取
    n-1+n-2+…+2+1=O(n^2)
    步骤,这取决于矩阵的标准和列是如何排序的

  • 然后您仍然需要收集
    n(n-1)
    单元格,即使是通过常数时间数组索引访问

这至少是我的推理。也许我错了。如果我错了,请解释为什么会错,以及下面代码的正确渐进运行时复杂性是什么

原作者的答复 扫描数组中的元素效率很低,但一旦有了索引,在该索引中查找元素的速度就会很快

给定标题行
header=[“foo”、“bar”、“foobar”]
@criteria=[“foobar”、“foo”]
,可以将它们转换为
索引

indices = @criteria.map{|column| header.index(column)}
# => [2, 0]
然后,使用
索引
,可以映射行:

[
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9],
]
.map{|row| row.values_at(*indices)}
其中:

[
  [3, 1],
  [6, 4],
  [9, 7],
]
通过这种方式,大部分计算复杂性在于创建
索引
,只需创建一次,花费的时间是可以忽略的,其余的都是按索引查找元素,复杂性很小,不像用户评论的那样

下面是使用上述方法的一些示例代码:

require 'csv'

@criteria = ['foobar', 'foo']

table = CSV.read('./foo.csv', headers: true)
indices = @criteria.map { |column| table.headers.index(column) }
table.map { |row| row.values_at(*indices) }

如果Ruby有一个很好的映射实现,并且假设数组足够小,可以很容易地放入内存中,那么我会将它实现为从每个列标题到一个按行包含列值的数组的映射。这样就可以很容易地选择列并对列进行排序。一般来说,我不认为可以通过矩阵的natu来改进操作再者,矩阵运算往往至少有
Omega(n^2)
运行时行为。如果您试图“按名称排序”,为什么在您的示例中“foobar”在“foo”之前?顺便问一下,您使用的是哪个版本的Ruby?有两个应用程序解析csv文件。这两个应用程序都需要特定(非统一)中的列运行ruby 2.0.0我不知道他们为什么删除它,因为这正是有效的!
require 'csv'

@criteria = ['foobar', 'foo']

table = CSV.read('./foo.csv', headers: true)
indices = @criteria.map { |column| table.headers.index(column) }
table.map { |row| row.values_at(*indices) }