Ruby新手在这里。我有一个产品csv,其中第一个col是唯一的SKU,第二个col是可以在多个产品中复制的产品ID(+许多其他cols,但这些是相关的)。像:
SKU | Prod ID
99 | 10384
100 | 10385
101 | 10385
102 | 10386
103 | 10386
104 | 10387
在我写的脚本中,第一次使用产品ID将成为“父”,产品ID的任何后续实例都会得到不同的处理(即不同的大小)。
目前正在阅读整个CSV而不是做foreach行,因为我认为我需要所有可用的数据来查找重复项。
问题是我不确定如何在第一次使用产品ID时识别,然后识别其使用的任何其他实例。
我的第一个想法是以某种方式识别重复项(uniq?),然后创建一个新列,如果它是第一次发生则放1,如果先前发生则放0。看完uniq之后,我不知道如何回到主列表并标记我的1和0。
有人可以指出我需要看的课程/方法的方向吗?
谢谢, 利安
为John D编辑:这给了我哈希,但是以1:1格式而不是1:所有prod ID实例
CSV.foreach(INPUT, :headers => true , :header_converters => :symbol, :col_sep => "|", :quote_char => "\x00") do |csv_obj|
items[csv_obj.fields[0]] = [csv_obj.fields[1]]
end
所以给出; “230709”=> [“88507”],“109064”=> [“9019”]
答案 0 :(得分:2)
您认为Sku
是唯一标识符,实际上它可能是唯一标识符。但是,如果您转过头来考虑ProductID
作为唯一标识符,那么您可以构建一个Hash
,其中键是ProductID
,值为Array
Sku
。然后,您就可以跟踪哪些Sku
与哪个ProductID
相关联。
当然,您将以其他方式阅读此内容,但最终结果将类似于:
products =
{
10384 => [99],
10385 => [100, 101],
10386 => [102, 103],
10387 => [104]
}
以下是如何构建此Hash的示例:
#!/usr/bin/env ruby
require 'csv'
source = [
"99|110384",
"100|10385",
"101|10385",
"102|10386",
"103|10386",
"104|10387"
].join("\n")
source = CSV.parse(source, :col_sep => "|")
hh = source.inject({}) do |memo, row|
sku = row[0]
prod = row[1]
memo[prod] = [] unless memo.include?(prod)
memo[prod] << sku
memo
end
puts hh
答案 1 :(得分:1)
.group_by()
相对较新(虽然它在Rails中有一个较旧的版本),但非常方便,应该完成你的大部分繁重工作。
如果您创建一个类来保存每一行并将它们放在Array
中,那么您可以使用仅检查每个对象的产品ID字段的块来调用group_by
方法。
这会为您提供Hash
,您可以使用.keys.each
进行迭代。
假设有很多关于你的程序的东西,希望是半明显的,比如:
transactionHash = transactions.group_by { |x| x.productId }
然后,您可以通过以下方式浏览每个产品的交易清单:
transactionHash.each do |prodId,transList|
# transList has all of your transaction objects per product
end
同样,这假设您将交易保留在对象列表中。例如,如果您将每个事务存储在数组中,x.productId
将类似于x[1]
。