【问题标题】:Check whether an array contains a value from another array检查一个数组是否包含另一个数组的值
【发布时间】:2017-04-29 22:08:23
【问题描述】:

我有一个对象数组,以及一个特定方法的可接受返回值数组。如何将对象数组减少到仅那些其方法在我的可接受值数组中返回值的对象?

现在,我有这个:

my @allowed = grep {
    my $object = $_;
    my $returned = $object->method;
    grep {
        my $value = $_;
        $value eq $returned;
    } @acceptableValues;
} @objects;

问题是这是一个复合循环,我想避免。该程序旨在扩展到任意大小,并且我想尽量减少运行的迭代次数。

最好的方法是什么?

【问题讨论】:

  • 将返回值放入哈希中。
  • 您期望有多少对象和可接受的值?

标签: arrays perl nested-loops


【解决方案1】:

您可以将接受的返回值转换为哈希

my %values = map { $_ => 1 } @acceptedValues;

grep 条件是密钥存在而不是你的 原始grep:

my @allowed = grep $values{ $_->method }, @objects;

不管怎样,grep 本身就相当快,这只是一个想法 检查元素是否在数组中的常用方法。尽量不要 优化不需要的东西,因为它只值得非常大 数组。然后,您可以例如对接受的结果数组进行排序,然后 使用二分搜索,如果重复,则缓存结果。但同样,不要 除非您要处理数百个问题,否则请担心这种优化 数以千计的项目 - 或更多。

【讨论】:

  • (实际上不需要exists,因为散列中的每个值都是真的)
  • @ikegami 是的,为了简单起见,我删除了它。不过,使用exists稍微快一点,对吧?
  • 如果它不能让你有时间冲泡咖啡,那么速度优化是不值得的。
【解决方案2】:

应该存在于给定数组中的元素似乎是独一无二的。因此,我将创建一个包含两个数组中元素计数的哈希。如果有任何元素的计数大于 1,则表示它存在于两个数组中。

my %values;
my @allowed;
map {$values{$_}++} (@acceptableValues, @objects);
for (keys %values) {
    push @allowed, $_ if $values{$_} > 1;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-06
    • 1970-01-01
    • 2015-10-28
    • 2017-05-30
    • 1970-01-01
    • 2016-02-06
    • 1970-01-01
    相关资源
    最近更新 更多