分组,在ruby中的数组数组

时间:2018-04-13 17:42:30

标签: arrays ruby

我有一个数组如下

    some_array = [["FANUC CORP", "100048", 9],
                  ["FANUC CORP", "100048", 26],
                  ["FANUC CORP", "100048", 23],
                  ["FANUC CORP", "100048", 111]]

我希望以下列方式分组:

=> ["FANUC CORP", "100048", [9, 26,23,111]]

任何人都可以提出建议,任何帮助都将受到赞赏

5 个答案:

答案 0 :(得分:3)

使用以下

some_array.group_by{|a| [a[0], a[1]]}
          .map{|key, value| key + [value.map(&:last)]}
          .flatten(1)

对于分组中的多个值

2.3.1 :046 > some_array = [["FANUC CORP", "100048", 9], ["FANUC CORP", "100048", 26]
   , ["FANUC CORP", "100048", 23], ["FANUC CORP", "100048", 111]
   , ["FANUC CORP", "100049", 19],["FANUC CORP", "100049", 126], 
     ["FANUC CORP", "100049", 123], ["FANUC CORP", "100049", 1111]]
 => [["FANUC CORP", "100048", 9], ["FANUC CORP", "100048", 26], 
    ["FANUC CORP", "100048", 23], ["FANUC CORP", "100048", 111], 
    ["FANUC CORP", "100049", 19], ["FANUC CORP", "100049", 126], 
    ["FANUC CORP", "100049", 123], ["FANUC CORP", "100049", 1111]] 

 2.3.1 :047 > some_array.group_by{|a| [a[0], a[1]]}
                        .map{|key, value| key + [value.map(&:last)]}
                        .flatten(1)
 => ["FANUC CORP", "100048", [9, 26, 23, 111], 
     "FANUC CORP", "100049", [19, 126, 123, 1111]] 

答案 1 :(得分:0)

some_array.
  map(&:dup).
  group_by { |arr| arr.shift(2) }.
  map { |k, v| [k + [v.flatten]] }
#⇒ [[["FANUC CORP", "100048", [9, 26, 23, 111]]]]

如果原始数组的所有元素具有相同的第一个和第二个元素,则调用.first

或者,对于您发布的确切案例,它更容易:

some_array.
  each_with_object(["FANUC CORP", "100048", []]) do |(_, _, v), acc|
    acc.last << v
  end
#⇒ ["FANUC CORP", "100048", [9, 26, 23, 111]]

答案 2 :(得分:0)

我想出了@mudasobwa和@salil答案之间的组合。

# backslashes so you can copy to console, remove them in a script

# mutates the original arrays
some_array.group_by { |a| a.shift(2) } \
          .flat_map { |k, v| k << v.flatten }

# doesn't mutate the original arrays
some_array.group_by { |a| a[0, 2] } \
          .flat_map { |k, v| k << v.map(&:last) }

#=> ["FANUC CORP", "100048", [9, 26, 23, 111]]

您也可以使用a[0, 2]更改a[0..1],无论您最喜欢什么。

答案 3 :(得分:0)

以下是获得所需回报值的两种方法。

arr = [
  [:a, "1", "c", 1],
  [:b, "2", "e", 4],
  [:a, "1", "c", 2], 
  [:b, "2", "e", 5],
  [:a, "1", "d", 3]
]

使用Hash#update的形式使用块来确定合并的两个哈希中存在的键的值。

arr.each_with_object({}) do |(*all_but_last, last), h|
  h.update(all_but_last=>[last]) { |_k,o,n| o+n }
end.map { |k,v| [*k,v] }
  #=> [[:a, "1", "c", [1, 2]], [:b, "2", "e", [4, 5]], [:a, "1", "d", [3]]]

有关块的三个变量Hash#updatemerge!_k的解释,请参阅o(又名n)的文档。 (_k保存公共密钥的值。变量名的第一个字符是下划线表示它不在块计算中使用。通常它只写_。)< / p>

请注意map的接收者如下。

arr.each_with_object({}) do |(*all_but_last, last), h|
  h.update(all_but_last=>[last]) { |_k,o,n| o+n }
end
  #=> {[:a, "1", "c"]=>[1, 2], [:b, "2", "e"]=>[4, 5], [:a, "1", "d"]=>[3]}

使用Enumerable#group_by

这有利于使用splat运算符。

arr.group_by { |*all_but_last,_| all_but_last }.
    map { |_,a| [*a.first[0..-2], a.map(&:last)] }
  #=> [[:a, "1", "c", [1, 2]], [:b, "2", "e", [4, 5]], [:a, "1", "d", [3]]]      

答案 4 :(得分:0)

使用import pandas as pd from datetime import datetime as dtt import matplotlib.pyplot as plt TnS_dataframe = pd.read_csv("data/TnS.csv") TnS_dataframe['EventTime'] = TnS_dataframe['EventTime'].map(lambda x: datetime.strptime(str(x[:19]), "%Y%m%d-%H%M%S.%f")) X = TnS_dataframe['EventTime'] Y = TnS_dataframe["Price"] # plot plt.plot(X,Y) # beautify the x-labels plt.gcf().autofmt_xdate() plt.show() transpose

yield_self