如何在 Perl 中将多个哈希值合并为一个哈希值?
在 Perl 中,我如何得到这个:
$VAR1 = { '999' => { '998' => [ '908', '906', '0', '998', '907' ] } };
$VAR1 = { '999' => { '991' => [ '913', '920', '918', '998', '916', '919', '917', '915', '912', '914' ] } };
$VAR1 = { '999' => { '996' => [] } };
$VAR1 = { '999' => { '995' => [] } };
$VAR1 = { '999' => { '994' => [] } };
$VAR1 = { '999' => { '993' => [] } };
$VAR1 = { '999' => { '997' => [ '986', '987', '990', '984', '989', '988' ] } };
$VAR1 = { '995' => { '101' => [] } };
$VAR1 = { '995' => { '102' => [] } };
$VAR1 = { '995' => { '103' => [] } };
$VAR1 = { '995' => { '104' => [] } };
$VAR1 = { '995' => { '105' => [] } };
$VAR1 = { '995' => { '106' => [] } };
$VAR1 = { '995' => { '107' => [] } };
$VAR1 = { '994' => { '910' => [] } };
$VAR1 = { '993' => { '909' => [] } };
$VAR1 = { '993' => { '904' => [] } };
$VAR1 = { '994' => { '985' => [] } };
$VAR1 = { '994' => { '983' => [] } };
$VAR1 = { '993' => { '902' => [] } };
$VAR1 = { '999' => { '992' => [ '905' ] } };
到这个:
$VAR1 = { '999:' => [
{ '992' => [ '905' ] },
{ '993' => [
{ '909' => [] },
{ '904' => [] },
{ '902' => [] }
] },
{ '994' => [
{ '910' => [] },
{ '985' => [] },
{ '983' => [] }
] },
{ '995' => [
{ '101' => [] },
{ '102' => [] },
{ '103' => [] },
{ '104' => [] },
{ '105' => [] },
{ '106' => [] },
{ '107' => [] }
] },
{ '996' => [] },
{ '997' => [ '986', '987', '990', '984', '989', '988' ] },
{ '998' => [ '908', '906', '0', '998', '907' ] },
{ '991' => [ '913', '920', '918', '998', '916', '919', '917', '915', '912', '914' ] }
]};
In Perl, how do I get this:
$VAR1 = { '999' => { '998' => [ '908', '906', '0', '998', '907' ] } };
$VAR1 = { '999' => { '991' => [ '913', '920', '918', '998', '916', '919', '917', '915', '912', '914' ] } };
$VAR1 = { '999' => { '996' => [] } };
$VAR1 = { '999' => { '995' => [] } };
$VAR1 = { '999' => { '994' => [] } };
$VAR1 = { '999' => { '993' => [] } };
$VAR1 = { '999' => { '997' => [ '986', '987', '990', '984', '989', '988' ] } };
$VAR1 = { '995' => { '101' => [] } };
$VAR1 = { '995' => { '102' => [] } };
$VAR1 = { '995' => { '103' => [] } };
$VAR1 = { '995' => { '104' => [] } };
$VAR1 = { '995' => { '105' => [] } };
$VAR1 = { '995' => { '106' => [] } };
$VAR1 = { '995' => { '107' => [] } };
$VAR1 = { '994' => { '910' => [] } };
$VAR1 = { '993' => { '909' => [] } };
$VAR1 = { '993' => { '904' => [] } };
$VAR1 = { '994' => { '985' => [] } };
$VAR1 = { '994' => { '983' => [] } };
$VAR1 = { '993' => { '902' => [] } };
$VAR1 = { '999' => { '992' => [ '905' ] } };
to this:
$VAR1 = { '999:' => [
{ '992' => [ '905' ] },
{ '993' => [
{ '909' => [] },
{ '904' => [] },
{ '902' => [] }
] },
{ '994' => [
{ '910' => [] },
{ '985' => [] },
{ '983' => [] }
] },
{ '995' => [
{ '101' => [] },
{ '102' => [] },
{ '103' => [] },
{ '104' => [] },
{ '105' => [] },
{ '106' => [] },
{ '107' => [] }
] },
{ '996' => [] },
{ '997' => [ '986', '987', '990', '984', '989', '988' ] },
{ '998' => [ '908', '906', '0', '998', '907' ] },
{ '991' => [ '913', '920', '918', '998', '916', '919', '917', '915', '912', '914' ] }
]};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我认为这比其他任何人都更接近:
这可以满足您的大部分需求。我没有将东西存储在单数数组中
哈希,因为我觉得这没有用。
您的场景不是常规场景。我试图在某种程度上概括这一点,
但无法克服该代码的奇点。
首先,因为看起来你想用相同的方式折叠所有内容
id 到合并实体(有例外),您必须向下遍历结构
拉取实体的定义。跟踪级别,因为您
希望它们以树的形式出现。
接下来,您将组装 ID 表,并尽可能合并实体。请注意,您
将 995 在一个地方定义为空数组,在另一个地方定义为级别。所以给出
你的输出,我想用哈希覆盖空列表。
之后,我们需要将根移动到结果结构,按顺序降序
将规范实体分配给每个级别的标识符。
就像我说的,这不是什么常规的事情。当然,如果你还想要一份清单
不超过对的哈希值,这是留给您的练习。
I think this is closer than anybody else has gotten:
This does most of what you want. I did not store things in arrays of singular
hashes, as I don't feel that that is useful.
Your scenario is not a regular one. I've tried to genericize this to some extent,
but was not possible to overcome the singularity of this code.
First of all because it appears you want to collapse everything with the same
id into a merged entity (with exceptions), you have to descend through the structure
pulling the definitions of the entities. Keeping track of levels, because you
want them in the form of a tree.
Next, you assemble the ID table, merging entities as possible. Note that you
had 995 defined as an empty array one place and as a level another. So given
your output, I wanted to overwrite the empty list with the hash.
After that, we need to move the root to the result structure, descending that in order
to assign canonical entities to the identifiers at each level.
Like I said, it's not anything that regular. Of course, if you still want a list
of hashes which are no more than pairs, that's an exercise left to you.
使用 CPAN!尝试 Hash::Merge
请参阅 CPAN 了解更多信息,它几乎可以完成您想要的所有操作,并且是完全可定制的。
Use CPAN! Try Hash::Merge
See CPAN for more info, it pretty much does everything you would want to, and is fully customizable.
尝试一下这个递归解决方案:
根据您的喜好修改它以达到所需的结果。
经过进一步调查,我注意到您正在以与上述算法不同的方式合并它们。也许就用这个作为例子吧。我的做法是这样的:
对于数组也有类似的事情。
Give this recursive solution a try:
Modify it to your hearts content to achieve the desired result.
Upon further investigation, I noticed you're merging them in some different way than the above algorithm. Maybe just use this as an example then. Mine does this:
And similar things for arrays.
我缩进了你想要的输出,因为它很难阅读,为了其他想要回答的人的利益。我还在想一个答案。
不过,我不明白所有这些单项哈希的意义,下面的不是更好吗?
I indented your wanted output as it was hard to read, for the benefit of other people who want to answer. I'm still thinking of an answer.
I don't see the point of all those single entry hashes though, would not the following be better?
假设上述数据位于文件 dump.txt 中,您可以逐条评估它。
更新下面的代码
如果你想完全深度合并,你可以在最后通过这个(未经测试!!!)深度合并传递 $final_data :
Assuming the above data is in a file dump.txt, you can eval it piece by piece.
Updated code below
If you want to completely deep merge, you can at the end pass $final_data through this (not tested!!!) deep merger:
使用
push
和autovivification。从通常的前题开始:
从
DATA
文件句柄中读取示例输入,并创建一个与您转储的数据结构类似的数据结构:您的输入有两种情况:
请注意
$_[0]
的使用。 Perl 子例程的语义是@_
中的值是别名而不是副本。这让我们可以直接调用merge
,而不必首先创建一堆脚手架来保存合并的内容。如果您复制该值,代码将会中断。现在,我们遍历
@hashes
并将其内容增量合并到%merged
中。我们不知道值到达的顺序,因此运行最后的清理过程来对数组进行排序:
Data::Dumper 模块非常适合快速调试!
将问题输入的副本放入特殊的
DATA
文件句柄中:输出示例如下:
Use
push
and autovivification.Start with the usual front matter:
Read your sample input from the
DATA
filehandle and create a datastructure similar to the one you dumped:Your input has two cases:
Note the use of
$_[0]
. The semantics of Perl subroutines are such that the values in@_
are aliases rather than copies. This lets us callmerge
directly without having to first create a bunch of scaffolding to hold the merged contents. The code will break if you copy the value instead.Now we walk
@hashes
and incrementally merge their contents into%merged
.We don't know in what order the values arrived, so run a final cleanup pass to sort the arrays:
The Data::Dumper module is great for quick debugging!
Place a copy of the input from your question into the special
DATA
filehandle:A sample of the output is below:
哇。非常感谢大家(特别是斧头人)!抱歉缺少代码或说明,我试图生成一棵树,并尝试了 Hash::Merge,但我无法解决用非空 995 替换空 995 的 coined-995 问题; Axeman 的解决方案运行良好,我非常感谢您的帮助/协作! (也尝试了其他方法,它要么做了与 Hash::Merge 相同的事情,要么实际上删除了一些分支)。
输入的一些背景:有一组哈希,每个哈希都有键(全部相同级别),其中两个定义了a)另一个的父级,b)本身(其余的是子级),因此对于一棵树,我认为哈希值是完美的,想出了一组新的哈希值 {a}->{b}->[c],我们在这里......
再次感谢大家和 Axeman!
wow. thanks so much everyone (especially Axeman)! sorry for the lack of code or clarification, I was trying to generate a tree, and did try Hash::Merge, but could not for the life of me resolve the coined-995 problem of replacing the empty 995 with the non-empty 995; Axeman's solution works beautifully and I really appreciate the help/collaboration! (also tried the others and it either did the same thing as Hash::Merge, or it actually got rid of some branches).
some background on the input: had a set of hashes, each had keys (all same level) and two of which defined a) a parent to another, and b) itself (the rest were children), and so with a tree, i figured a hash was perfect, came up with a set of new hashes {a}->{b}->[c], and here we are...
again, thanks everyone and Axeman!