根据另一个列表中唯一值的索引从一个列表中获取相应的值 - Perl

时间:2012-08-23 13:58:27

标签: perl

我想根据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'1''a'对应'e'而2nd'a'对应'a'。所以第二个被删除而不是第一个。

2 个答案:

答案 0 :(得分:3)

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

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];
}

答案 1 :(得分: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'
        ];