【问题标题】:Check specific value not in array检查不在数组中的特定值
【发布时间】:2015-04-30 01:47:03
【问题描述】:

我有一个包含两个值的数组,如果输入不在该数组中,则需要执行一些操作。

我试过了

if ($a ne ('value1' || 'value2')

if (($a ne 'value1' ) || ($a ne 'value2' ))

这两种方法都不起作用。有人可以帮忙吗?

【问题讨论】:

标签: perl compare


【解决方案1】:

您可以使用List::MoreUtils 中的none 函数。

如果您确实有一个数组,如主题行所述,那么您的代码将如下所示

use List::MoreUtils 'none';

if ( none { $_ eq $a } @array ) {
  # Do stuff
}

或者如果你真的有两个常量,那么你可以使用这个

if ( none { $_ eq $a } 'value1', 'value2' ) {
  # Do stuff
}

但在这种情况下,我宁愿只看到

if ( $a ne 'value1' and $a ne 'value2' ) {
  # Do stuff
}

【讨论】:

  • ++ 我从来没有想过这种方式,但Smart::Match 就像一个“Util”模块一样运行。它还有一个none 函数,您可以在其中执行:if ( $x ~~ none (@array) ) {say "not here so do stuff"}。就好像它对Match::Util 的未来(非常简化)版本的~~ 运算符进行了增强。添加Smart::Match 作为响应。
  • @G.Cito:我喜欢给智能匹配或与之相关的任何东西一个非常广泛的泊位,我害怕必须使用 Perl 6 版本编写任何数量的代码。问题是它试图成为一个 DWIM 运算符,并且不可能记住它对任何给定的参数组合做了什么。我会尽快说出我的意思并得到正确的结果,并让其他人理解我的代码
  • 我可以看到它可能是如此“智能”以至于难以简化。简化某些事情可能很复杂,但要做到正确需要很长时间。
  • @G.Cito:通常,智能匹配运算符执行List::MoreUtils中可用的功能之一。如果您添加引用的取消引用,那么您几乎已经涵盖了它,并且每个 不同的 操作也有不同的名称,因此您不会在任何地方都写$thing1 MAGIC $thing2。即使是面向对象的代码也可能会出现这样的问题,而这正是我想去的地方
【解决方案2】:

如果$a 与第一个元素不同并且它也与第二个元素不同,则$a 不在数组中。

if ($x ne 'value1' and $x ne 'value2') {

对于任意大小的实数数组:

if (not grep $_ eq $x, @array) {

(我使用$x 而不是$a,因为$a 是特殊的 - 请参阅perlvar。)

【讨论】:

  • 保留和流量控制;在表达式中使用 &&
  • @VadimPushtaev 当您检查数组中是否有 is 时,这当然是有效的,但在这种情况下,我们正在检查是否有 not 在数组中,这必然需要遍历每个元素。你可以使用grepList::MoreUtils::none,选择你的毒药。
  • @ThisSuitIsBlackNot,不,这是错误的。 none 不一定会遍历每个元素,它会在第一次匹配后停止,就像 any
  • @VadimPushtaev 啊,你是对的。如果没有匹配项,您只需遍历每个元素。
【解决方案3】:
if ($a ne ('value1' || 'value2')

评估为

if ($a ne 'value1')

if (($a ne 'value1' ) || ($a ne 'value2' ))

总是正确的。

你可以试试

if ($a ne 'value1' and $a ne 'value2')

if (!grep{$a eq $_} 'value1', 'value2')

【讨论】:

  • @VadimPushtaev:我认为 应该避免 夸大了它。这只是 Perl Best Practices 的法令之一,原因是 grep 比较列表中的 所有 元素,而不管较早的匹配是否可以缩短 -电路的过程。只要牢记这一点,grep 就是这样做的好方法,特别是因为列表只有两项长度,并且额外的计算在任何也从磁盘文件读取数据的代码中都是微不足道的
【解决方案4】:

以@Dilbertino(好昵称)的智能匹配解决方案为基础,使用@tobyink 的match::simple 来缓解智能匹配消失的痛苦(我已经想念它了):

use match::simple;
my @array = qw(abcd.txt abcdeff.txt abcdweff.txt abcdefrgt.txt);
my $x="abcd.txt" ;
say "it's there" if ($x |M| \@array );

match::simple 中的 |M| 运算符可以替换为 match 函数,这会加快速度(它是用 XS 实现的):

use match::simple qw(match);
my @array = qw(abcd.txt abcdeff.txt abcdweff.txt abcdefrgt.txt);
my $x="xyz.txt" ;

if ( match ( $x, \@array ) ) {
     say "it's there!" ;
}
else {
     say "no hay nada";
} 

这很“简单”,因为 RHS 控制着行为。使用match::simple,如果您要匹配 RHS 上的数组,它应该是一个数组引用。

Smart::Match 也有一个none 函数。要使用它,你会这样做:

if ( $x ~~ none (@array) ) { 
   say "not here so do stuff ..."; 
}

附录

在 Stackoverlfow(参见:Perl 5.20 and the fate of smart matching and given-when?)和其他地方(c.f.@ikegami 来自大约 perl-5.18 的Perlmonks article)的讨论给出了智能匹配实验的背景。 TLDR; 未来可能会发生变化,但与此同时,您可以回到过去use match::smart qw(match); 使用 perl-5.8.9 再次证明 perl 永远不会消亡;它只是回到了它的生态系统。

在未来,类似Smart::Match。非核心 CPAN 模块不是概念)可以帮助增强简化的智能匹配运算符,其辅助函数读起来像副词和形容词,并且具有由于~~ 运算符的操作上下文不那么模糊,因此为 perl 本身澄清/简化了事情的额外好处(据我所知)。

【讨论】:

  • 自从我的那些帖子之后,p5p 上就再也没有出现过这个话题了。有兴趣的人需要加紧
【解决方案5】:

我会使用 grep 和正则表达式匹配来做这样的事情

#!/usr/bin/perl
use warnings;
use strict;

my @array = ('value1','value2');

if(grep(/\bvalue1\b|\bvalue2\b/, @array)){
    print "Not Found\n";
}
else {
    print "do something\n";
}

【讨论】:

【解决方案6】:

您还可以使用智能匹配运算符:

除非($x ~~ ['value1','value2'])

【讨论】:

  • 如果/当它消失时,我会想念“~~”。 @tobyink 总是有match::simple
  • 只是为了澄清@G.Cito 对智能匹配消失的评论......智能匹配是marked experimental in 5.18.0:“很明显,智能匹配几乎肯定会改变或消失未来。不建议依赖其当前行为。”
  • @ThisSuitIsBlackNot 谢谢,我试图在回复中进一步澄清一下。引导 p5p perlmonks 和 @ikegami @leont 似乎我们可能希望在 Perl 的未来版本中出现更简单的 ~~ 版本——其行为可以通过实用程序模块和 CPAN 生态系统得到增强和扩展。 /我交叉手指
【解决方案7】:

您的变量$a 不会被评估为没有[INDEX] 索引的array,而是被视为标量。

两个值array

$array[0] = "X"; $array[1] = "Y";

@array = qw/X Y/;

使用if进行条件检查:

if ( $array[0] ne "Your-String" || $array[1] ne "Your-String")

【讨论】:

  • 我认为示例代码的呈现方式假定@array 的值与$a 的值匹配。这不是最清晰的示例代码,但应该是 OP 来更改它。
猜你喜欢
  • 1970-01-01
  • 2011-05-29
  • 2018-10-13
  • 1970-01-01
  • 1970-01-01
  • 2011-10-22
  • 1970-01-01
  • 2012-09-04
相关资源
最近更新 更多