*阅读本文的最后一节,了解避免边缘情况问题的最稳定技术——它也是最冗长的。
单行无循环:(Demo)
var_export(array_keys(array_intersect(array_count_values($array),[1])));
细分:
array_keys( // return the remaining keys from array_count_values
array_intersect( // filter the first array by second
array_count_values($array), // count number of occurrences of each value
[1] // identify the number of occurrences to keep
)
)
如果您(或任何未来的读者)想要保留更多值,请替换 array_intersect() 中的第二个参数/数组。
例如:
您想保留 1、2 和 3:array(1,2,3) 或 [1,2,3]
附言作为记录,您可以使用 array_filter() 和自定义函数来省略所有非 1 的计数值,但我使用了 array_intersect(),因为语法更简洁且 IMO 更易于阅读。
附言以为我会重新审视并包含 PHP7.4 技术并与其他基于函数的技术进行比较...
代码:(Demo)
$numbers = [4, 3, 4, 3, 1, 2, 1];
var_export(
array_keys(
array_intersect(
array_count_values($numbers),
[1]
)
)
);
echo "\n---\n";
var_export(
array_keys(
array_filter(
array_count_values($numbers),
function($count) {
return $count === 1;
}
)
)
);
echo "\n---\n";
// PHP7.4+
var_export(
array_keys(
array_filter(
array_count_values($numbers),
fn($count) => $count === 1
)
)
);
*对于具有不保证为整数的值的类似任务,array_count_values() 将报错“警告:array_count_values(): Can only count string and integer values”。
即使像@LF00's answer这样使用值作为第一级键的经典循环也会由于浮点数和数值被自动转换为整数而遭受潜在的副作用。
这意味着更通用的解决方案是:(Demo)
$result = [];
foreach ($array as $index => $value) {
foreach ($array as $i => $v) {
if ($value === $v && $index !== $i) {
continue 2; // duplicate found, stop checking this value; do not retain
}
}
$result[] = $value;
}
var_export($result);