寻找在阵列共同要素 [英] Finding common elements in arrays

查看:131
本文介绍了寻找在阵列共同要素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个哈希值,其值是数组。我需要找到这些阵列的共同要素,
IE浏览器。这是在所有阵列present的元素。所以我提取的哈希值成
多维数组的每一行对应于散列的数组。然后,我把第一行
这个矩阵到另一个阵列(@ ARR1),并通过它迭代查找是否有任何元件
在ARR1那也是在矩阵的行的其余部分。如果找到这样的元件,它是
推到一个包含所有元素的最后名单另一个数组。在code是如下
(我希望这是足够清晰):

I have a hash whose values are arrays. I need to find the common elements of those arrays, ie. the elements that are present in all the arrays. So I extracted the values of the hash into a multidimensional array whose each row corresponds to an array in the hash. Then I took the first row of this matrix into another array (@arr1) and iterated through it to find if there was any element in arr1 that was also in the rest of the rows of the matrix. If such an element is found, it is pushed onto another array that contains the final list of all the elements. The code is as follows (I hope it is clear enough):

sub construct_arr(my %records) {
    my $len = keys %records;
    my @matrix;
    my $i = 0;

    # Extract the values of the hash into a matrix
    foreach my $key (keys %records) {
        $matrix[$i] = $records{$key};
        $i++;   
    }

    my @arr1 = $matrix[0];
    my @final;

    # Iterate through each element of arr1
    for my $j (0..$#{$arr1[0]}) {
        my $count = 1;

        # Iterate through each row of the matrix, starting from the second
        for ( my $i = 1; $i < $len ; $i++ ) {
            my $flag = 0;

            # Iterate through each element of the row
            for my $k (0..$#{$matrix[$i]}) {
                if ($arr1[0][$j] eq $matrix[$i][$k]) {
                    $flag = 1;
                    $count++;
                }
            }

            # On finding the first instance of the element in a row, go to the next row
            if (!$flag == 1) {
                last;
            }       
        }

        # If element is in all the rows, push it on to the final array
        if ($count == $len) {
            push(@final, $arr1[0][$j]);
        }
    }
    return @final;
}

我知道,上面的作品,但我想知道是否有任何其他的(Perl的)的方式来做到这一点。
我开始学习Perl和我在知道的东西,可以让我的工作变得更容易很感兴趣
在Perl比其他语言。如果我的code是可以做的最好,请让我知道,
太。任何指导,将AP preciated。谢谢!

I know that the above works, but I would like to know if there is any other (perlish) way to do this. I am starting to learn perl and I am very interested in knowing things that could make my work easier in perl as compared to other languages. If my code is the best that can be done, please let me know that too. Any guidance would be appreciated. Thanks!

推荐答案

看看克里斯·查理的的链接计算数组的交集。

Take a look at Chris Charley's link for calculating the intersection of arrays.

哈希是明确的路要走,像这样的问题。连同地图的grep 解决方案可以减少到只需几行。

Hashes are the clear way to go for problems like this. Together with map and grep a solution can be reduced to just a few lines.

此程序使用孙大信的数据,因为没有更好一些,似乎做什么你所需要的。

This program uses sundar's data for want of anything better, and seems to do what you need.

use strict;
use warnings;

my %records = (
  a => [ qw/ A B C / ],
  b => [ qw/ C D E A / ],
  c => [ qw/ A C E / ],
);

print "$_\n" for construct_arr(\%records);

sub construct_arr {
  my $records = shift;
  my %seen;
  $seen{$_}++ for map @$_, values %$records;
  grep $seen{$_} == keys %$records, keys %seen;
}

输出

A
C


修改

我想这可能有助于看到一个更加Perlish的,自己的解决方案的整理版本。

I thought it may help to see a more Perlish, tidied version of your own solution.

use strict;
use warnings;

my %records = (
  a => [ qw/ A B C / ],
  b => [ qw/ C D E A / ],
  c => [ qw/ A C E / ],
);

print "$_\n" for construct_arr(\%records);

sub construct_arr {

  my $records = shift;
  my @matrix = values %$records;
  my @final;

  # iterate through each element the first row
  for my $i ( 0 .. $#{$matrix[0]} ) {

    my $count = 1;

    # look for this value in all the rest of the rows, dropping
    # out to the next row as soon as a match is found
    ROW:
    for my $j ( 1 .. $#matrix ) {
      for my $k (0 .. $#{$matrix[$j]}) {
        next unless $matrix[0][$i] eq $matrix[$j][$k];
        $count++;
        next ROW;
      }
    }

    # If element is in all the rows, push it on to the final array
    push @final, $matrix[0][$i] if $count == @matrix;
  }

  return @final;
}

的输出是相同的为自己的方案,但功能却略有不同,因为雷假定每行中的值是唯一的。如果SAMA值多次出现我的解决方案将打破更多的(同样适用于孙大信的的)。请让我知道,如果这是可以接受的。

The output is the same as for my own program, but the functionality is slightly different as mine assumes the values in each row are unique. If the sama value appears more than once my solution will break (the same applies to sundar's). Please let me know if that is acceptable.

这篇关于寻找在阵列共同要素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆