我有一组嵌套到多个级别的哈希。我需要从所有深度嵌套的哈希中提取一个值,该哈希值对同一哈希中的不同键具有给定值
这是我们数据库中的实体集合,数据代表每个实体内的联系人及其所有联系人值。
有一个哈希键// run with:
// /home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/casperjs/bin/casperjs --engine=slimerjs test_load_utf8.js
var utf8 = require('utf8');
var casper = require('casper').create({
//~ verbose: true,
//~ logLevel: 'debug',
userAgent: 'Mozilla/5.0 (X11; Linux i686; rv:43.0) Gecko/20100101 Firefox/43.0',
viewportSize: {width: 1024, height: 768},
pageSettings: {
loadImages: false,//The script is much faster when this field is set to false
loadPlugins: false,
}
});
casper.on("page.initialized", function(page) {
page.captureContent = [ /json/ ]; // slimerJS only (0.10.1-pre)
page.onResourceReceived = function(response) {
var turl = response.url;
if (turl.indexOf("getjson") > -1) {
if (response.stage == "end") {
if (response.body.length > 0) {
console.log(" resp.body: " + response.body);
}
}
}
};
});
//First step is to open page
casper.start().thenOpen("http://127.0.0.1:8080/test_load_utf8.php", function() {
console.log("website opened");
});
//Second step is to click to the button
casper.then(function(){
this.evaluate(function(){
document.getElementById("getdatabtn").click();
});
});
casper.run();
,它引用一个定义联系方法类型的整数。我关心的contact_method_type_id
是1,这是电子邮件。
第一次联系有三种不同的contact_methods。第一个是办公室电话4,第二个是家庭电话2,第三个是电子邮件1。
在同一个哈希中,有一个'contact_method_value',这是他们电子邮件地址的字符串表示。
我需要一种方法将这些值提取到一个新数组
以下是数组第一个元素
的内容contact_method_type_id
答案 0 :(得分:1)
如果数据结构都是同一种类,那么这非常简单。您只需要迭代所有外部hashrefs(我称之为 resultsets )。在这些内容中,您需要查看所有结果,并且在每个结果中,您需要查看所有联系方法。如果其中一个人的contact_method_type_id
为1,则可以使用contact_method_value
。就是这样。
my @email_addresses;
foreach my $resultset ( @{$data} ) {
foreach my $result ( @{ $resultset->{results} } ) {
foreach my $contact ( @{ $result->{contact_methods} } ) {
push @email_addresses , [ $contact->{contact_method_value} ]
if $contact->{contact_method_type_id} == 1;
}
}
}
此代码假定您的结构名为$data
。输出时@email_addresses
看起来像这样。
[
[ 'EMAIL' ],
[ 'EMAIL' ]
];
答案 1 :(得分:1)
这看起来很像XML::Simple
会产生的东西。
假设是这种情况,那么我建议你已经因为假设XML::Simple
实际上有所帮助的经典错误而陷入困境。
根据该假设,如果您改为使用XML::Twig
:
带上你的$VAR1
。虽然 - 理想情况下,您只需使用parse
或parsefile
解析原始来源:
use XML::Twig;
use XML::Simple;
my $twig = XML::Twig->parse( XMLout($VAR1) );
print $_->att('contact_method_value'), "\n" for $twig->findnodes('//contact_methods[@contact_method_type_name="Email"]');
给出了您的样本($VAR1
):
example@example.com
example@example.com
编辑:因为你评论它是JSON
然后我不一定会这样做(尽管 - 尽管如此,它确实有效)。
答案 2 :(得分:0)
如果您在数据库上有这个,那么您应该使用SQL查询来检索它,而不是将所有内容提取到内存中并处理您拥有的内容
Data::Dumper
的输出显示了您数据的内容,但它并未解释您在代码中处理的内容。具体来说,您的代码中没有$VAR1
,但我不知道您 做 的内容
最后,我想I wouldn't start from here。但由于它是我必须使用的唯一起点,因此通过数据结构递归是一件简单的事情
我以为你想要
$VAR1->[*]{results}[*]{contact_methods}[*]{contact_method_value}
,其中
$VAR1->[*]{results}[*]{contact_methods}[*]{contact_method_type_name} eq 'Email'
<强> 更新 强>
自您发表评论后,我改变了我的代码以选择相同的值
$VAR1->[*]{results}[*]{contact_methods}[*]{contact_method_type_id} == 1
由于您根本没有说明您的代码,我必须假设一个变量$data
,其中包含您在问题中显示的数组的引用
for my $item ( @$data ) {
my $results = $item->{results};
for my $result ( @$results ) {
my $methods = $result->{contact_methods} or die;
for my $method ( @$methods ) {
#my $type_name = $method->{contact_method_type_name};
#next unless $type_name eq 'Email';
my $type_id = $method->{contact_method_type_id};
next unless $type_id == 1; ## Email
my $value = $method->{contact_method_value};
print "$value\n";
}
}
}
example@example.com
example@example.com