【问题标题】:How to add each element of array to another array's each element?如何将数组的每个元素添加到另一个数组的每个元素?
【发布时间】:2018-06-22 16:25:25
【问题描述】:

我有这些数组集,每个数组有两个元素。

@a = ("a", "b");

@i = (1, 2);

@s = ( "\\!", "\?");

如何使结果返回

a1!,b2?

而且我需要它们成为一组新的数组,例如

@new =(a1!,b2?)

我写了输出答案的代码

$i = length(@a);

for (0..$1) {

    @array = push(@array, @a[$i], @s[$i];

}

print @array;

但是,它只返回了

syntax error at pra.pl line 10, near "];"

提前谢谢你。

【问题讨论】:

  • 请显示您尝试过的代码并解释什么不起作用。要求我们为您编写代码是一种非常可靠的方式来累积反对票并让您的问题搁置。
  • 我这样做了,它返回 systax erroe$i = length(@a); for (0..$1) { @array = push(@array, @a[$i], @s[$i]; } print @array;
  • edit您的问题并在那里添加代码。
  • 感谢您的建议,编辑了我的问题。

标签: arrays perl


【解决方案1】:
use 5.008;
use List::AllUtils qw(zip_by);
⋮
my @new = zip_by { join '', @_ } \@a, \@i, \@s;

zip_by 是 CPAN 上 List::AllUtils 模块的子程序。所以它不是内置的。


use v6;
⋮
my @new = map { .join }, zip @a, @i, @s;

在 Perl 6 中,zip 已经是标准库的一部分。这个额外的解决方案是为了品味,它是一个展示优势的机会:做同样的工作,但相比之下语法更少,而且开箱即用。

v6 不是绝对必要的,这里我只是用来对比来表示版本。但是在文件的开头,它也有一个很好的属性,如果你不小心在 Perl 5 中运行 Perl 6 代码,你会得到一个很好的错误消息,而不是一个神秘的语法错误。试试看!来自use VERSION documentation

如果 VERSION 大于当前 Perl 的版本,则会引发异常

【讨论】:

  • zip_by是内置函数还是用户定义的变量?你能解释一下 v6 到底是做什么的吗?我对这些我不熟悉的术语进行了一些研究,但我无法清楚地理解这个概念。帮助会很棒,谢谢!
  • 我编辑了回答您的问题的答案,因为 cmets 中没有足够的空间。 HTH!
【解决方案2】:

您的基本想法很好,即使用数组的索引同时迭代。但是该代码有许多基本错误,并且它也没有按照示例显示的那样做。我建议首先通读一个现代且有声望的 Perl 教程。

这些示例表明您希望在每个索引处连接(参见. operator)元素

use warnings;
use strict;
use feature 'say';

my @a1 = ('a', 'b');
my @a2 = (1, 2);
my @a3 = ('!', '?');

my @res;
foreach my $i (0..$#a1) {
    push @res, $a1[$i] . $a2[$i] . $a3[$i];
}

say for @res;

其中$#a1 是数组@a1 的最后一个元素的索引。这假设所有数组都具有相同的大小并且它们的所有元素都已定义。

这个确切的工作可以在一个语句中使用map 来完成

my @res = map { $a1[$_] . $a2[$_] . $a3[$_] } 0..$#a1;

具有相同的、严肃的假设。即使您知道他们持有,您是否知道肯定,在任何数据的每次运行中?如需稳健的方法,请参阅answer by mwp

还有来自List::MoreUtilseach_array,为所有数组提供“同时迭代器”

my $ea = each_array(@a1, @a2, @a3);

my @res;
while ( my ($e1, $e2, $e3) = $ea->() ) {
    push @res, $e1 . $e2 . $e3
}

这对于更复杂的处理非常有用。

快速浏览基础知识

  • 在程序的开头总是有 use warnings;use strict;。他们会发现许多错误,否则会花费大量时间和精力。

  • 不要使用单字母变量名。我们很快就会忘记它们的意思,代码变得难以理解,而且它们很容易犯愚蠢的错误。

  • 数组的大小不是length 给出的。它通常使用context 获得——当一个数组被分配给一个标量时,它的元素数被返回。对于索引的迭代,有$#ary@ary 的最后一个元素的索引。那么索引列表是0 .. $#ary,使用range (..) operator

  • 标识符(变量名)开头的符号($@%)表示type of the variable(标量、数组、哈希)。数组元素是一个标量,所以它需要$ -- $ary[0]

  • push 不返回数组元素,而是在其第一个参数中将后面列表中的标量添加到数组中。

  • print @array; 打印数组元素,它们之间没有任何内容。当您引用它时,会添加空格,print "@array\n";。请注意方便的feature say,它添加了新行。

【讨论】:

  • @Seho 欢迎 :)。感谢您按照 Jim 的建议编辑问题 :)
【解决方案3】:
  1. 始终使用use strict;use warnings;(并使用my 声明变量)。
  2. 您无需在 Perl 字符串中转义 ?!,并且可以使用 qw// 类似引号的运算符轻松构建术语列表。
  3. 您使用length(@a) 来确定最后一个索引,但是Perl 数组索引是从零开始的,所以最后一个索引实际上是length(@a) - 1。 (但这仍然不对。请看下一点……)
  4. 要在 Perl 中获取数组的长度,您需要在标量上下文中计算它。 length 函数用于字符串。
  5. 您没有考虑数组长度不同的情况。
  6. 您将最后一个索引分配给变量$i,但随后在下一行引用了变量$1。这是两个不同的变量。
  7. 您正在从零迭代到最后一个索引,但没有将迭代器显式分配给变量,也没有使用隐式迭代器变量 ($_)。
  8. 要在 Perl 中按索引获取单个数组元素,语法是 $a[$i],而不是 @a[$i]。因为您只需要一个标量值,所以表达式必须以标量符号$ 开头。 (如果您想要一个表达式中的值列表,则可以使用数组 sigil @ 开始表达式。)
  9. push 修改了第一个参数给出的数组,因此不需要将结果分配回表达式中的数组。
  10. push 表达式中缺少右括号。
  11. 在您的相同代码中,您有 @new@array,并且您只添加来自 @a@s 的元素(即您忘记了 @i)。
  12. 您将元素推送到数组中,但并未将它们连接成所需的字符串格式。

这是您的实现的工作版本:

use strict;
use warnings;

use List::Util qw{max};

my @a = ("a", "b");
my @i = ("1", "2");
my @s = ("!", "?");

my @array;
my $length = max scalar @a, scalar @i, scalar @s;

foreach my $i (0 .. $length - 1) {
  push @array, ($a[$i] // '') . ($i[$i] // '') . ($s[$i] // '');
}

print @array;

// 的意思是“定义或”。)

我可以这样写:

use strict;
use warnings;

use List::Util qw{max};

my @a = qw/a b/;
my @i = qw/1 2/;
my @s = qw/! ?/;

my @array = map {
  join '', grep defined, $a[$_], $i[$_], $s[$_]
} 0 .. max $#a, $#i, $#s;

print "@array\n";

$#a 的意思是“给我数组@a 的最后一个元素的索引。”)

【讨论】:

  • 您正在从零迭代到最后一个索引,但您没有将迭代器分配给变量,因此您无法访问它。 实际上,它在$_.
【解决方案4】:
use warnings;
use strict;    
use Data::Dumper;

my $result = [];
my @a = ("a", "b");
my @i = (1, 2);
my @s = ( "\!", "\?");

my $index = 0;
for my $a ( @a ) {
  push( @$result, ($a[$index], $i[$index], $s[$index]) );
  $index = $index + 1;
}

print Dumper(@$result);

【讨论】:

  • 请在您希望用户复制和学习的代码中使用strictwarnings
猜你喜欢
  • 2015-08-15
  • 2021-03-20
  • 1970-01-01
  • 1970-01-01
  • 2014-07-07
  • 1970-01-01
  • 1970-01-01
  • 2022-11-03
  • 2018-07-26
相关资源
最近更新 更多