如何通过存储在变量中的索引访问哈希值 [英] How to access a hash value by index stored in variable

查看:53
本文介绍了如何通过存储在变量中的索引访问哈希值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理一些代码,以从网页中提取以JSON格式存储的数据.提取JSON数据并将其正确解码为哈希.

I am working on some code to extract data stored in JSON format from web page. JSON data extracted and decode properly into hash.

JSON数据的结构非常复杂,我编写了一些辅助代码/函数,它们遍历"哈希并帮助找到哈希中感兴趣的值的索引"(位置).

The structure of JSON data is very complex, I wrote some assisting code/function which 'traverse' through the hash and helps finds 'index' (location) of a value of interest in the hash.

查找"功能返回散列中存储在变量中的数据的索引"(位置).

The 'find' function returns 'index' (location) of the data in the hash which stored in a variable.

我尝试在其他操作中使用此变量(存储的索引"),但到目前为止没有成功.

I attempt to use this variable (stored 'index') in other operations but so far without any success.

请参阅随附的简单演示代码段中的问题说明.

Please see included simple demo snippet code for explanation of the problem.

谢谢你,北极熊

use strict;
use warnings;

use JSON qw(decode_json);

my $index;
my $slice;

my $data = decode_json( join '', <DATA> );

printf "TITLE: %-15s TIME: %5s TIMES: %5s FAVORITE: %s\n",
        $data->{playList}[1]{title},
        $data->{playList}[1]{time},
        $data->{playList}[1]{played},
        $data->{playList}[1]{favorite} ? "yes" : "no";

$index = '{playList}[1]';

$slice = $data{$index};     # does not pass 'use strict' compilation error
$slice = $data->{$index};   # empty slice 
$slice = $data->$index;     # Can't call method "{playList}[1]" on unblessed reference at

printf "TITLE: %-15s TIME: %5s TIMES: %5s FAVORITE: %s\n",
        $slice->{title},
        $slice->{time},
        $slice->{played},
        $slice->{favorite} ? "yes" : "no";

__DATA__
{
    "playList": [
      {
        "title": "Song name 1",
        "time": "3:25",
        "played": "240",
        "favorite": "1"
      },
      {
        "title": "Song name 2",
        "time": "4:12",
        "played": "30",
        "favorite": "0"
      },
      {
        "title": "Song name 3",
        "time": "2:56",
        "played": "85",
        "favorite": "0"
      }
    ]
}

我希望通过利用存储在变量中的索引"来访问数据,但是我找不到实现此结果的方法.有关详细信息,请参见代码中的注释.

I expect to access data by utilizing 'index' stored in a variable but I could not find a way to achieve this result. See comments in the code for details.

注意:在现实生活中,索引看起来如下

NOTE: In real life the index looks as following

my $index = "{contents}{twoColumnBrowseResultsRenderer}{tabs}[0]{tabRenderer}{content}{sectionListRenderer}{contents}[0]{itemSectionRenderer}{contents}[0]{playlistVideoListRenderer}{contents}[0]{playlistVideoRenderer}{title}{accessibility}{accessibilityData}{label}";

解决方案:

我想感谢您向HåkonHægland和lordadmira致谢

I would like to extend my 'thank you' to Håkon Hægland and lordadmira for offered solution

use Data::Diver qw/Dive/; # or Data::DPath, etc

# Capture web page, extract data JSON, convert to hash, assign hash ref to $data
my $data = ...; 

# Find index/location in the hash
#my $index = find($data, $value);

my $index = "{contents}{twoColumnBrowseResultsRenderer}{tabs}[0]{tabRenderer}{content}{sectionListRenderer}{contents}[0]{itemSectionRenderer}{contents}[0]{playlistVideoListRenderer}{contents}[0]{playlistVideoRenderer}{title}{accessibility}{accessibilityData}{label}";

$index =~ s/[{\[]//g; # throw away opening brackets

my @index = split /[}\]]/, $index; # split into array on closing brackets

pop @index for 1..8 # 8 levels to back up to

my $slice = Dive( $data, @index ); # extract hash slice of interest

# extract playlist
my $playlist = $slice->{playlistVideoListRenderer}{contents};

# go through playlist and extract information of our interest
foreach ( @$playlist ) {
    my $video = $_->{playlistVideoRenderer};
    printf "%s %8s %s\n",
            $video->{videoId},
            $video->{lengthText}{simpleText},
            $video->{title}{simpleText};
}

他们两个都在这个模块的帮助下将我引荐给 use Data :: Dive ,我可以从哈希的深度备份几级并提取切片.

Both of them referred me to use Data::Dive with help of this module I can do back up few levels from the depth of the hash and extract slice of interest.

据了解,通过利用此模块,以 array 形式出现的索引更易于使用.由于这个因素,我将更改我的find函数以返回索引数组.

It was learned that by utilizing this module the index in form of array is easier to work with. Due this factor I will alter my find function to return an index array.

推荐答案

在注释中,您说您有一个函数可以在JSON数据结构中找到一个元素,并返回该元素的路径",并且问题是要找到该元素的更高级别的容器.

In the comments, you said you had a function that finds the an element in your JSON data structure and returns a "path" to that element, and that your question is about finding a higher-level container of that element.

如果这是XML,我将使用XPath进行搜索并找到正确的容器.但是不用担心,有人开发了类似JSON的XPath语言,并且有人提供了此功能通过Perl模块 JSON :: Path .

If this was XML, I'd use an XPath to do both the search and finding the right container. But worry not, someone has devlopped an XPath-like language for JSON, and someone has provide this functionality via Perl module JSON::Path.

这篇关于如何通过存储在变量中的索引访问哈希值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆