简体   繁体   English

如何从Perl中的地图返回hashrefs列表?

[英]How can I return a list of hashrefs from a map in Perl?

I have the following mostly ok code: 我有以下几乎正常的代码:

my $results = { data => [
   map {
      my $f = $_->TO_JSON;
      $f->{display_field} = $_->display_field($q);
      $f;
   } $rs->all
]};

Only I'd rather it were more like the following: 只有我更喜欢它更像是以下内容:

my $results = { data => [
   map {
      %{$_->TO_JSON},
      display_field => $_->display_field($q),
   }, $rs->all
]};

But that gives a syntax error. 但是这会产生语法错误。 How can I do what I want, or is my current version the best it gets? 我怎样才能做我想要的,或者我现在的版本是最好的?

update : sorry about the extra semicolon from before. 更新 :抱歉以前的额外分号。 It's late here. 现在已经很晚了。 Not sure how I missed it. 不知道我是怎么错过它的。 Thanks guys! 多谢你们!

It only gives a syntax error because you Perl thinks you need to omit the comma after map { ... } , because it is parsing that map as being a block, not an expression. 它只提供语法错误,因为Perl认为你需要在map { ... }之后省略逗号,因为它将该映射解析为块,而不是表达式。 Putting + in front will fix that. +放在前面会解决这个问题。 Also, you can't have a semicolon in an anonymous hash: 此外,您不能在匿名哈希中使用分号:

my $results = { data => [
   map +{
#      ^----------------- plus sign added
      %{$_->TO_JSON},
      display_field => $_->display_field($q);
#                                           ^---- should be comma or nothing
   }, $rs->all
]};

The problem is that Perl doesn't look ahead far enough to figure out whether { means "start an anonymous hash reference" or "start a code block". 问题是Perl看起来不够远,无法确定{意味着“启动匿名哈希引用”还是“启动代码块”。 It should (ideally) look to the corresponding } and see if there is or isn't a comma, and act accordingly, but it doesn't. 应该 (理想情况下)查看相应的}并查看是否存在逗号,并采取相应的行动,但事实并非如此。 It only looks a little bit ahead and tries to guess. 它只是看起来有点前进并试图猜测。 And this time it's wrong, and you get a syntax error about a comma that shouldn't be there, except that it should so don't move it. 这次是错的,你得到一个不应该存在的逗号的语法错误,除了它应该不移动它。

perldoc -f map will tell you all about this. perldoc -f map会告诉你所有这些。 Basically, it says that if you put +{ , Perl will understand that this means "not a code block" and guess that it's a hash reference. 基本上,它说如果你把+{ ,Perl会理解这意味着“不是代码块”并猜测它是一个哈希引用。 This is probably the cause of your syntax error. 这可能是您的语法错误的原因。 As another suggestion, it might work to say map({ HASH STUFF }, $rs->all) - I bet money Perl won't guess it's a code reference here. 作为另一个建议,可能会说map({ HASH STUFF }, $rs->all) - 我打赌钱Perl不会猜测它是这里的代码参考。

I couldn't get it to work, but not having $rs or a ->TO_JSON or a variable named $q I couldn't get any of this to work anyway. 我无法让它工作,但没有$rs->TO_JSON或一个名为$q的变量我无论如何都无法使用任何这个。 I hope this helps. 我希望这有帮助。 If not, post a little more code. 如果没有,请发布更多代码。 Don't worry, we don't bite. 别担心,我们不咬人。

Also, while we're at it, why not write it this way: 此外,虽然我们在这,但为什么不这样写:

my $results;
$results->{data} = [ map MAGIC MAP STUFF, $rs->all ];

Might arguably be more readable, especially if you're adding a lot of stuff to $results all at once. 可能有可能更具可读性,特别是如果你同时在$results添加了很多东西。

I'm not completely sure what kind of structure you're looking for. 我不完全确定你正在寻找什么样的结构。 The map in your first example already returns a list of hashrefs (every version of $f ). 第一个示例中的map已经返回hashrefs列表(每个版本的$f )。

If you just want syntax similar to your second example, then you were almost right; 如果您只想要与第二个示例类似的语法,那么您几乎是正确的; you need to get rid of the extraneous semicolon in your map block, and use a pair of curlies to make an anonymous hash ref. 你需要摆脱你的地图块中无关的分号,并使用一对curlies来制作一个匿名的散列引用。

Something like: 就像是:

my $results = { data => [
    map { { %{$_->TO_JSON},
            display_field => $_->display_field($q)
          }
    } $rs->all
]};

I just always use map in the block form, and structure the code so it's easy to pick apart. 我总是在块形式中使用map,并构造代码以便于分离。 Although you can put a + in front of the opening curly to use the expression form, does it really matter to you that much? 虽然你可以在开头卷曲前放一个+来使用表达形式,但这对你真的很重要吗?

Aside from everything else going on, your first example looks fine. 除了发生的一切,你的第一个例子看起来很好。 Move on and solve real problems. 继续前进并解决实际问题。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM