【问题标题】:Can I use Perl's map with an array slice?我可以将 Perl 的映射与数组切片一起使用吗?
【发布时间】:2009-11-06 08:22:39
【问题描述】:

我只是想缩短将 HTML::Element->as_trimmed_text 从 HTML::Elements 数组分配给一些变量的代码行 - 非常标准的东西,例如:

my ($var1, var2) = ($columns[1]->as_trimmed_text, $columns[2]->as_trimmed_text);

..除了还有几列,所以它继续多几行。我有一个好主意,我可以使用 map 代替,但我真的没有太多运气。我已经尝试过

map { $_->as_trimmed_text } @columns[1, 3, 5, 7, 9]

但我不断收到无法在没有包或对象引用的情况下调用方法“as_trimmed_text”。

是否可以做我正在尝试的事情,还是应该坚持我目前拥有的?

TIA

编辑:列 -> 列

【问题讨论】:

  • 目前看起来您正在使用不同的变量:@column 在第一个示例中,@columns 在第二个示例中。但是map使用的思路还可以
  • 这行得通吗? map { $columns[$_]->as_trimmed_text } 1, 3, 5, 7, 9
  • 您可能需要围绕您正在做的事情添加更多代码;这对我来说是正确的。
  • 假设您没有遇到column -v- columns 打字问题,请向我们展示您的代码的实际有效行,以及您尝试用它替换的内容不起作用。
  • 实际上,从头开始:我已经复制了您的问题。诡异的。看得更远。

标签: perl arrays map subscript


【解决方案1】:

找到了:

这里有一段代码模拟了应该发生的事情:

use strict;
use warnings;

package Text;

sub new
{
   my $class = shift;
   my $text = shift;
   return bless { TEXT => $text }, $class;
}

sub as_trimmed_text
{
   my $self = shift;
   my $text = $self->{TEXT};
   $text =~ s/^\s*(.*?)\s*$/$1/;
   return $text;
}

package main;

my @texts = ( Text->new(' foo '), Text->new(' bar '), Text->new(' baz '));

my @trimmed = map { $_->as_trimmed_text() } @texts[1, 2];

print "Trimmed were: ", join(',', map { "'$_'" } @trimmed);

这行得通,而且工作正常;我明白了:

Trimmed were: 'bar','baz'

但如果我用这一行替换地图:

my @trimmed = map { $_->as_trimmed_text() } @texts[2, 3];

突然间我得到了这个输出:

Can't call method "as_trimmed_text" on an undefined value

这是因为“3”超出了@texts 中的有效值范围,因此它会自动激活一个新条目,并将其设为undef。然后,你的地图就可以了

undef->as_trimmed_output()

哪个呕吐物。我会再次检查您的数组切片,并确保您没有在可用的实际索引之外获取值,除此之外,请验证您实际上是在使用 map 处理 HTML::Element 成员。对@columns 中的值的快速Data::Dumper::Dumper 将有很大帮助。

例如,如果您将数组更改为包含

my @texts = ( Text->new(' foo '), Text->new(' bar '), ' baz ');

并尝试运行它,我现在收到您的错误:

Can't call method "as_trimmed_text" without a package or object reference at map.pl

因此,请仔细检查以确保您的数组的内容实际上都是您尝试调用其方法的类的所有受祝福的实例。

【讨论】:

  • 像这样迟到的(可能)正确答案让我很伤心,因为我没有投票了。
  • @Chris:你说了很多(你希望你可以投票等)。为什么不干脆第二天回来投票?
  • 这是最有可能的答案,排除了错别字假设:)
【解决方案2】:

您的map 对我来说很合适。你确定第二个应该说@columns而不是@column吗?您是否打开了strict 以捕捉变量名中的拼写错误?

【讨论】:

  • 对不起,输入代码只是为了给出一个简短的例子。是的,我总是使用严格和警告。
  • @pavium 注意use strictrocks 与使用严格的rocks 之间的区别。
【解决方案3】:

首先,如果您对 map 的输出不感兴趣,则不应使用 map。 Map 和 grep、sort 等一样是一个过滤器。如果您不想要输出,请使用 foreach。

但你是对的,map 正是为了解决这类问题而设计的。这将提供您想要的输出,尽管它不使用数组切片。

@trimmed_columns = map { $column[$_]->as_trimmed_text } (1, 3, 5, 7, 9);

Robert P's answer 更好地解释了为什么原版不起作用。

【讨论】:

  • -1。这个答案只有真实的陈述,它有有效的代码,但它没有解决这个问题,即使用map 和一个数组切片。它也没有解释原始代码出了什么问题。
  • 我想你在技术上是正确的。我更关心以最正确的方式为他的问题提供解决方案,而不是回答发布的确切问题。由于 perl 将数组切片视为不可变列表,因此使用 map 内联修改它(无论如何你都不应该这样做)将是解决问题的错误方法。我将修改我的答案以使其更具表现力。
  • 问题中的代码没有修改任何东西,使用数组切片也没有任何问题...
【解决方案4】:

您在第二个示例 @columns 中使用了另一个变量,但不是 @column。尝试使用以下代码:

map { $_->as_trimmed_text } @column[1, 3, 5, 7, 9]

【讨论】:

    猜你喜欢
    • 2012-03-18
    • 1970-01-01
    • 2013-03-11
    • 1970-01-01
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    • 2015-11-30
    • 2020-03-23
    相关资源
    最近更新 更多