我有两个哈希数组,看起来像这样:
h1=[{id:1, item:1, value:10},
{id:1, item:2, value:3}]
h2=[{id:1, item_a:1, value:5},{id:2, item_a:1, value:7},{id:3, item_a:1, value:10},
{id:4, item_b:2, value:1},{id:5, item_b:2, value:2},{id:6, item_b:2, value:5},
{id:7, item_b:2, value:1}]
我需要遍历h2
和:
h1
哈希,找到h2
哈希,其item
对应item_a
,例如item
值为1
和{ {1}}值为item_a
,1
中取value
,直到所有项目的总和等于或大于h2
哈希h1
中的项目,value
和h1
创建一个id数组数组,其第一个值为h2
id
,第二个值为h1
来自{{1} }}。在上面的示例中,结果为id
。
我在这里找到this answer,但它只是将值总结到某个定义的限制。我不知道如何获取值,直到达到总和的一部分。我希望有人可以指导我应该关注的方向。
更新
结果h2
是因为:
[[1,1],[1,2],[1,4],[1,5]]
我们会在[[1,1],[1,2],[1,4],[1,5]]
和h1
处获取第一个哈希值,因此我们需要从item:1
收集value:10
的ID,因为我需要{{1} }}和h2
值(在现实生活中 - ids),我们的总价值至少应为item_a:1
1
并从第一个哈希开始 - 其1
小于10
所以我们接受它,然后我们转到下一个哈希 - 它的h2
和如果我们将其总结为之前的value:5
,我们得到10
- 它大于value:7
所以我们接受它并停止迭代,因为我们不允许再采取任何项目。我们的第一次迭代结果是:来自5
哈希的{是12
,来自10
哈希的ID是h1
和1
。所以到目前为止我们的数组是h2
1
的第二个哈希做同样的事情,其中2
的匹配 ID 为[[1,1],[1,2]]
和h1
。更新2
我正在清除我的例子,因为在两个哈希中只能有h2
。
我想扩展我的例子。
如果在4
和5
中添加额外条件item
- from
日期范围和to
条件,代码会如何变更?
date
我想仅从那些h1
h2
h1=[{id:1, item:1, from: DateTime.new(2017,9,4,6,0,0,'+0300'), to: DateTime.new(2017,9,4,17,59,59,'+0300'), value:10},
{id:1, item:2, from: DateTime.new(2017,9,4,18,0,0,'+0300'), to: DateTime.new(2017,9,4,23,59,59,'+0300'), value:10}]
h2=[{id:1, item:1, date: DateTime.new(2017,9,4,6,10,0,'+0300'), value:5},
{id:2, item:1, date: DateTime.new(2017,9,4,7,20,0,'+0300'), value:7},
{id:3, item:1, date: DateTime.new(2017,9,4,8,05,0,'+0300'), value:10},
{id:4, item:2, date: DateTime.new(2017,9,4,18,19,10,'+0300'), value:1},
{id:5, item:2, date: DateTime.new(2017,9,4,19,20,0,'+0300'), value:2},
{id:6, item:2, date: DateTime.new(2017,9,4,22,22,0,'+0300'), value:5},
{id:7, item:2, date: DateTime.new(2017,9,4,23,0,0,'+0300'), value:1}]
date
h2
个h1
日from
范围内的哈希中获取ID。我想我应该把这个to
放在某个地方。
答案 0 :(得分:2)
首先我做了几个假设,你在描述中根本没有提到item_b
,只说明h1
和{{1}之间的链接}是关键h2
,所以我假设item_a
和item_a
是等价的......也就是说,你不会有item_b
之类的东西您不希望考虑item_b: 1
中的第一个哈希值,因为它是h1
而不是item_b
。如果情况不正确,您需要相应调整以下代码(不应该太难)。
首先,如果您使用item_a
键对h2
中的项目进行分组会更容易,这样您就可以对它们进行简单的查找:
item_a/item_b
现在,h2 = h2.group_by { |item| item[:item_a] || item[:item_b] }
# => {1=>[ {:id=>1, :item_a=>1, :value=>5},
{:id=>2, :item_a=>1, :value=>7},
{:id=>3, :item_a=>1, :value=>10} ],
2=>[ {:id=>4, :item_b=>2, :value=>1},
{:id=>5, :item_b=>2, :value=>2},
{:id=>6, :item_b=>2, :value=>5},
{:id=>7, :item_b=>2, :value=>1} ]
}
包含映射到h2[1]
第一行的所有项目(基于h1
键)。接下来,您要将item
中的值映射到数组列表,其中h1
来自id
,h1
来自id
和{{1}来自h2
的{s}来自id
循环,跟踪总和:
h2
最后,您需要压平1级才能获得所需的结果:
take_while
答案 1 :(得分:1)
我对:item_a
中的密钥:item_b
和:item_c
(以及大概h2
等)也有疑问。可以假设:item_a
属于h1[0]
,:item_b
到h1[1]
,依此类推,但是更容易让它们具有相同的名称,我选择了是:item
。也就是说,item_a
和item_b
不会使问题变得更加困难,它只会从编码的角度引入麻烦。
h1 = [{ id:1, item:1, value:10 }, { id:1, item:2, value:3 }]
h2 = [{ id:1, item:1, value:5 }, { id:2, item:1, value:7 }, { id:3, item:1, value:10 },
{ id:4, item:2, value:1 }, { id:5, item:2, value:2 }, { id:6, item:2, value:5},
{ id:7, item:2, value:1 }]
我假设,对于g
中的每个哈希h1
,如果g[:value]
大于f[:value]
的总和f
{ {1}} h2
,f[:item] = g[:item]
,对于所有此类哈希值[g[:id], f[:id]
,将包含在返回的数组中。 (哇!)相反,如果f
应该被忽略,则g
的值之和不足,只需要对下面的代码进行少量更改。
第一步是从h2
构建另一个哈希。
h2
如您所见,h = h2.each_with_object({}) do |g, h|
h.update(g[:item]=>[[g[:id], g[:value]]]) do |_, o, n|
o << [g[:id], o.last.last + g[:value]]
end
end
#=> {1=>[[1, 5], [2, 12], [3, 22]], 2=>[[4, 1], [5, 3], [6, 8], [7, 9]]}
的密钥等于h
的值,以及:item
值对和:id
的“累积”值对的数组值。
:value
计算h1.each_with_object([]) do |g, a|
id1 = g[:id]
value1 = g[:value]
arr = h[g[:item]]
i = arr.index { |_id2, cum| value1 <= cum } || (arr.size - 1)
arr[0..i].map(&:first).each { |id2| a << [id1, id2] }
end
#=> [[1, 1], [1, 2], [1, 4], [1, 5]]
后的步骤如下:
h
如果有a = []
g = { id:1, item:1, value:10 }
id1 = g[:id]
#=> 1
value1 = g[:value]
#=> 10
arr = h[g[:item]]
#=> h[1]
#=> [[1, 5], [2, 12], [3, 22]]
i = arr.index { |_id2, cum| value1 <= cum } || (arr.size - 1)
#=> 1
,说value1
,我们会获得100
。在这种情况下,arr.index { |_id2, cum| value1 <= cum } #=> nil
设置为等于“或”字词i
。
arr.size - 1
其余的计算方法类似。