4

我想我可以用这样的 foreach 循环来做到这一点:

 foreach ($haystack as $item)
       if (isset($item->$needle_field) && $item->$needle_field == $needle)
            return true;
 } 

但我在徘徊是否可以在没有循环的情况下完成?

就像是:

  if(in_array($item->$needle_field == $needle,$haystack)
            return true;
4

4 回答 4

6

是的,在现代 PHP 中,您可以通过结合array_column()(已经演变为也处理对象数组)和in_array().

代码:(演示

$objects = [
    (object)['cats' => 2],
    (object)['dogs' => 2],
    (object)['fish' => 10],
    (object)['birds' => 1],
];

$needleField = 'cats';
$needleValue = 2;

var_export(
    in_array($needleValue, array_column($objects, $needleField))
);
// output: true

这种技术的优点是明显简洁的语法。对于相对少量的数据,这是一种完全可以接受的方法。

这种技术的一个可能的缺点是,array_column()它将生成一个包含所有与$needleField.

在我上面的演示中,array_column()将只生成一个单元素数组,因为cats所有对象中只有一个属性。如果我们正在处理相对大量的数据,那么费心收集所有符合条件的cats值然后in_array()在只需要返回一个匹配项时运行将是低效的true

对于“大量”数据,其中性能是脚本设计的主要标准,经典foreach循环将是更好的选择,一旦对象满足规则,则应通过returnor停止循环break

代码:(演示

function hasPropertyValue(array $objects, $property, $value): bool {
    foreach ($objects as $object) {
        if (property_exists($object, $property) && $object->{$property} === $value) {
            return true;
        }
    }
    return false;
}
var_export(
    hasPropertyValue($objects, $needleField, $needleValue)
);
于 2020-11-15T11:25:32.923 回答
4

这是可能的,但也不是更好:

<?php
function make_subject($count, $success) {
    $ret = array();
    for ($i = 0; $i < $count; $i++) {
        $object = new stdClass();
        $object->foo = $success ? $i : null;
        $ret[] = $object;
    }
    return $ret;
}

// Change true to false for failed test.
$subject = make_subject(10, true);

if (sizeof(array_filter($subject, function($value) {
    return $value->foo === 3;
}))) {
    echo 'Value 3 was found!';
} else {
    echo 'Value 3 was not found.';
}

输出Value 3 was found!

我建议您继续使用 for 循环:它清晰易读,与保存您可能找到的行的任何技巧不同。

于 2013-09-10T23:04:36.897 回答
0

如果您正在搜索的数组超出您的控制范围,这将不起作用。但是,如果您是构建要搜索的对象数组的人,您可以使用 needle 作为数组键来构建它,以便在搜索时与array_key_exists一起使用。

例如,不要$haystack像这样制作数组:

[
  {
    'needle_field' => $needle
  },
  ...
]

让它像这样:

[
  $needle => {
    'needle_field' => $needle
  },
  ...
]

并像这样搜索:

if (array_key_exists($needle, $haystack)) {
  return true;
}

最后,如果需要,可以使用array_values转换回整数索引数组

$haystack = array_values($haystack);

这可能不适用于所有情况,但对我来说效果很好。

于 2019-08-30T16:51:15.330 回答
-1

也许与array_key_exists

if (array_key_exists($needle_field, $haystack) { 
  if ($haystack[$needle_field] == $needle) {
    echo "$needle exists";
  }
}
于 2013-09-10T23:36:51.250 回答