0

我想使用 perl 根据我的第一个列表中唯一值的索引值从第二个列表中获取相应的值。

例如:

@list1=('a','b','c','a','d');
@list2=('e','f','g','a','i');

我想创建两个没有重复值的新列表

@new_list1=('a','b','c','d');
@new_list2=('e','f','g','i');

我怎样才能做到这一点?

要从一个列表中获取唯一值,我可以使用:

my %temp_hash = map { $_, 0 } @list1;
my @uniq_array = keys %temp_hash;   
print "@uniq_array\n";

但是如何从另一个列表中获取相应索引处的值。

提前致谢。

编辑:它应该根据某些条件而不是第一次出现找到唯一值。例如:

@list1=('a','b','c','a','d');
@list2=('e','f','g','a','i');

@list1=('a','b','c','a','d');
@list2=('a','f','g','e','i');

应该给出相同的值:

@new_list1=('a','b','c','d');
@new_list2=('e','f','g','i');

在给定的示例中,条件可能是不包括两个列表的值相同的公共元素。即有两次出现'a'第一次'a'对应于'e',第二个'a'对应于'a'。所以要删除第二个而不是第一个。

4

2 回答 2

3

在处理并行数组时,需要处理索引。要查找索引列表,可以从以下查找唯一值的常用方法开始:

my %seen;
my @uniq = grep !$seen{$_}++, @dups;

并展开它以将索引列表作为输入:

my %seen;
my @indexes = grep !$seen{ $list1[$_] }++, 0..$#list1;

在您更新的问题中,您需要更复杂的东西:

my %options;
for (0..$#list1) {
   push @{ $options{ $list1[$_] } }, $_;
}

my %seen;
my @indexes;
for (0..$#list1) {
   next if $seen{$_}++;
   my @options = @{ $options{ $list1[$_] } };
   my $option = pick(\@list1, \@list2, \@options) // $options[0];
   push @indexes, $option;
}

然后您所要做的就是提取所需的元素:

my @new_list1 = @list1[ @indexes ];
my @new_list2 = @list2[ @indexes ];

您描述的可能选择算法的pick功能是:

sub pick {
   my ($list1, $list2, $options) = @_;
   return ( grep $list1->[$_] ne $list2->[$_], @options )[0];
}
于 2012-08-23T14:02:59.803 回答
0
use strict;
use warnings;
use Data::Dumper;

my @list1=('a','b','c','a','d');
my @list2=('e','f','g','a','i');

my %hash1 = ();
my %hash2 = ();

$hash1{$_}++ for @list1;

my @uniq_list1 = sort keys %hash1;

for (@list2)
{
    next if defined ($hash1{$_});
    $hash2{$_}++;
}
my @uniq_list2 = sort keys %hash2;

print Dumper(\@uniq_list1);
print Dumper(\@uniq_list2);

输出:

$VAR1 = [
          'a',
          'b',
          'c',
          'd'
        ];

$VAR1 = [
          'e',
          'f',
          'g',
          'i'
        ];
于 2012-08-23T14:17:15.137 回答