web-dev-qa-db-ja.com

perlで2つの配列をマージし、各配列の値を交互にする方法

以下のような2つの配列があると仮定します

@a1 = ("Vinay", Raj, harry);
@b1 = ("dude","rock");

マージした後、私はこのような結果が欲しい

[
    Vinay
    dude
    Vinay
    rock
    Raj
    dude
    Raj
    rock
    harry
    dude
    harry
    rock
]

基本的に、array1の各インデックス値をarray2のすべてのインデックス値にマージします。

上記の質問に追加する別のクエリがあります。

上記の同じ質問に対して、特定の配列インデックスで2つの配列をマージする方法について。たとえば、各160要素の2つの配列がありますが、セット内の5番目の要素ごとに配列をマージしたいのですが、可能ですか?

16
Vinay D

これを行う1つの方法を次に示します。ただし、最高のPerl構文ではない場合があります。 double forループは、2つの配列のすべての組み合わせをマージされた配列にプッシュすることを意味します。結果が質問で指定した順序になるように設定しようとしました。

my @merged;

for my $a ( @a1 ) {
  for my $b ( @b1 ) {
    Push( @merged, ($a, $b) );
  }
}
10
mattc

新しい配列を作成するだけです:

my @merged = (@a1, @b1);

完全な例を次に示します。

my @a1 = ("foo", "bar");
my @a2 = ("baz", "spam");

my @merged = (@a1, @a2);

print $merged[3]; #=> "spam"

[〜#〜] edit [〜#〜]:注文の要件を逃しました。それらを一緒にZipする必要があります。これはList::MoreUtils

use List::MoreUtils qw(Zip);
use Data::Dumper qw(Dumper);

my @a1 = ("Vinay", "Raj", "harry");
my @a2 = ("dude", "rock");

my @merged = Zip(@a1, @a2);

print Dumper(\@merged);
53
jmdeldin

別のオプションを次に示します。

use strict;
use warnings;
use Data::Dumper;

my $a = join ',', qw/Vinay Raj harry/;
my $b = join ',', qw/dude rock/;

my @merged = map { split '-' } glob "{$a}-{$b}";

print Dumper \@merged;

出力:

$VAR1 = [
          'Vinay',
          'dude',
          'Vinay',
          'rock',
          'Raj',
          'dude',
          'Raj',
          'rock',
          'harry',
          'dude',
          'harry',
          'rock'
        ]
4
Kenosis

まず、ベアワードを使用しないでください。jmdeldinのコメントに記載されているように、常にuse strict; use warnings;スクリプトの開始時。

これらのリストの作成方法@a1および@b1?引用符を使用します:

my @a1 = ('Vinay', 'Raj', 'harry');
my @a2 = ('dude', 'rock');

または、qwを使用します。

my @a1 = qw(Vinay Raj harry);
my @a2 = qw(dude rock);

これらを指定どおりに「マージ」する方法は? 1つの方法は、ネストされたループのペアを使用することです。さらに簡潔に、mapmapを使用します。

my @merged = map {my $outer = $_; map {($outer, $_)} @b1} @a1;

Perl 5.12の特別な機能は必要ありません。リストが崩壊するという事実を利用してください。

4
David Hammen

それは1行でひどく行われる可能性があります。

@merged = grep {not ref} map {[our $t = $_], map {$t,$_} @b1} @a1;

プッシュインで少し残酷になります

map {our $t = $_, map {Push(@merged, $t, $_)} @b1} @a1;
1
Basil

使用する Set::CrossProduct CPANから。

List :: MoreUtilsのZipは、引数リストの対応する(およびcrossではない)インデックスの要素を圧縮します。

0
vapace