Ruby数组以日期为键进行哈希

时间:2018-07-01 09:03:43

标签: ruby

我有一个看起来像这样的数组:

private static string GetDiffText(decimal diff)
{
    var abs = Math.Abs(diff);
    string diffText;

    var absoluteValue = abs.ToString("C", CultureInfo.InvariantCulture);
    if (diff >= 0)
    {
        diffText = $"+{absoluteValue}";
    }
    else
    {
        diffText = $"-{absoluteValue}";
    }
    return diffText;
}

我想要作为输出的是一个哈希,其中日期用作键:

[
  ["20180630", "14:49", "google", "iOS", "Safari", "1"], 
  ["20180630", "12:22", "google", "Android", "Chrome", "2"],
  ["20180629", "17:20", "google", "iOS", "Safari", "1"], 
  ["20180629", "16:30", "(direct)", "iOS", "Safari", "1"], 
  ["20180629", "09:29", "(direct)", "Android", "Chrome", "2"]
]

2 个答案:

答案 0 :(得分:2)

Enumerable#group_by将为您提供数组的哈希转换,然后只需从结果值中删除冗余列即可。

hash = input_array.group_by(&:first)
hash.each { |_, list| list.each(&:shift) }
hash

(请注意,它会修改原始数组;如果有问题,您需要将其调整为具有更多复制和更少变异的版本)

答案 1 :(得分:2)

这里有两种构建所需哈希的方法。都不会更改给定的数组(arr)。

arr = [
  ["20180630", "14:49", "google", "iOS", "Safari", "1"], 
  ["20180630", "12:22", "google", "Android", "Chrome", "2"],
  ["20180629", "17:20", "google", "iOS", "Safari", "1"], 
  ["20180629", "16:30", "(direct)", "iOS", "Safari", "1"], 
  ["20180629", "09:29", "(direct)", "Android", "Chrome", "2"]
]

arr.each_with_object({}) { |a,h| (h[a.first] ||= []) << a.drop(1) }
  #=> {"20180630"=>[["14:49", "google", "iOS", "Safari", "1"],
  #                 ["12:22", "google", "Android", "Chrome", "2"]],
  #   "20180629"=>[["17:20", "google", "iOS", "Safari", "1"],
  #                ["16:30", "(direct)", "iOS", "Safari", "1"],
  #                ["09:29", "(direct)", "Android", "Chrome", "2"]]}

以下是一个变体。

arr.each_with_object(Hash.new { |h,k| h[k] = [] }) { |a,h| h[a.first] << a.drop(1) }

或者,可以使用Hash#update的形式(又称merge!),该形式采用一个块来确定要合并的两个哈希中存在的键的值。

arr.each_with_object({}) { |a,h| h.update(a.first=>[a.drop(1)]) { |_,o,n| o+n } }