我有一个 PHP 数组,如下所示:
$messages = [312, 401, 1599, 3, ...];
我想删除包含值 $del_val
的元素(例如 $del_val=401
),但我不知道它的键。这可能会有所帮助:每个值只能出现一次。
我正在寻找最简单的功能来执行此任务,拜托。
使用 array_search()
和 unset
,尝试以下操作:
if (($key = array_search($del_val, $messages)) !== false) {
unset($messages[$key]);
}
array_search()
返回它找到的元素的键,可用于使用 unset()
从原始数组中删除该元素。它会在失败时返回 FALSE
,但是它可以在成功时返回 false-y 值(例如,您的键可能是 0
),这就是使用严格比较 !==
运算符的原因。
if()
语句将检查 array_search()
是否返回了值,并且只有在返回时才会执行操作。
好吧,从数组中删除一个元素基本上只是用一个元素设置 difference。
array_diff( [312, 401, 15, 401, 3], [401] ) // removing 401 returns [312, 15, 3]
它很好地概括了,如果你愿意,你可以同时删除尽可能多的元素。
免责声明:请注意,我的解决方案会生成数组的新副本,同时保持旧副本完整,而接受的答案会发生变异。选择你需要的那个。
[$element]
时遇到了“解析错误”,我改用了 array($element)
。没什么大不了的,只是想让有类似问题的人知道他们并不孤单
array_diff
使用 (string) $elem1 === (string) $elem2
作为其相等条件,而不是您可能期望的 $elem1 === $elem2
。 @nischayn22 指出的问题是由此产生的结果。如果您希望将某些东西用作适用于任意元素数组(可能是对象)的实用函数,出于这个原因,Bojangle 的答案可能会更好。
array_diff()
的每个参数执行排序,因此将运行时从 O(n) 微调到 O(n lg n)。
一种有趣的方法是使用 array_keys()
:
foreach (array_keys($messages, 401, true) as $key) {
unset($messages[$key]);
}
array_keys()
函数采用两个附加参数来仅返回特定值的键以及是否需要严格检查(即使用 === 进行比较)。
这也可以删除具有相同值的多个数组项(例如 [1, 2, 3, 3, 4]
)。
array_values()
;其余的键仍然是相同的顺序,所以从技术上讲它不是“未排序的”
array_keys()
可以进行搜索。
如果您确定您的数组将只包含一个具有该值的元素,您可以这样做
$key = array_search($del_val, $array);
if (false !== $key) {
unset($array[$key]);
}
但是,如果您的值可能在您的数组中出现多次,您可以这样做
$array = array_filter($array, function($e) use ($del_val) {
return ($e !== $del_val);
});
注意: 第二个选项仅适用于带有 Closures 的 PHP5.3+
$fields = array_flip($fields);
unset($fields['myvalue']);
$fields = array_flip($fields);
最好的方法是array_splice
array_splice($array, array_search(58, $array ), 1);
[1, 2, 4 => 3]
。
3
后,数组将是 [1, 2, 3]
;换句话说,该值没有被删除。需要明确的是,我并不是说它在所有情况下都失败了,只是这个。
或者简单地说,手动方式:
foreach ($array as $key => $value){
if ($value == $target_value) {
unset($array[$key]);
}
}
这是其中最安全的,因为您可以完全控制您的阵列
array_splice()
而不是 unset()
也会重新排序数组索引,在这种情况下可能会更好。
在 PHP 7.4 中使用箭头函数:
$messages = array_filter($messages, fn ($m) => $m != $del_val);
要将其保留为非关联数组,请使用 array_values()
将其包装:
$messages = array_values(array_filter($messages, fn ($m) => $m != $del_val));
foreach()
循环,但这更简洁。
function array_remove_by_value($array, $value)
{
return array_values(array_diff($array, array($value)));
}
$array = array(312, 401, 1599, 3);
$newarray = array_remove_by_value($array, 401);
print_r($newarray);
输出
Array ( [0] => 312 [1] => 1599 [2] => 3 )
你可以做:
unset($messages[array_flip($messages)['401']]);
说明:翻转数组后删除键为401
的元素。
401
怎么办?
要删除多个值,试试这个:
while (($key = array_search($del_val, $messages)) !== false)
{
unset($messages[$key]);
}
接受的答案会将数组转换为关联数组,因此,如果您想将其作为接受答案的非关联数组,您可能必须使用 { 1}也是。
if(($key = array_search($del_val, $messages)) !== false) {
unset($messages[$key]);
$arr = array_values($messages);
}
参考是 here
如果您不知道它的密钥,则意味着它无关紧要。
您可以将值作为键,这意味着它会立即找到该值。比一遍又一遍地在所有元素中使用搜索要好。
$messages=array();
$messages[312] = 312;
$messages[401] = 401;
$messages[1599] = 1599;
$messages[3] = 3;
unset($messages[3]); // no search needed
PHP 7.4 或以上
function delArrValues(array $arr, array $remove) {
return array_filter($arr, fn($e) => !in_array($e, $remove));
};
所以,如果你有数组
$messages = [312, 401, 1599, 3];
并且您想从 $messages 数组中删除两个 3, 312
,您可以这样做
delArrValues($messages, [3, 312])
它会回来
[401, 1599]
最好的部分是您可以轻松过滤多个值,即使同一值多次出现。
array_filter
版本的扩展形式可以用于旧版本的 php,例如: ` array_filter( $arr, function($arg) use ($black_list) { return !in_array($arg, $black_list) ; } ); `
借用 underscore.JS _.reject 的逻辑,创建了两个函数(人们更喜欢函数!!)
array_reject_value:此函数只是拒绝指定的值(也适用于 PHP4、5、7)
function array_reject_value(array &$arrayToFilter, $deleteValue) {
$filteredArray = array();
foreach ($arrayToFilter as $key => $value) {
if ($value !== $deleteValue) {
$filteredArray[] = $value;
}
}
return $filteredArray;
}
array_reject:此函数只是拒绝可调用方法(适用于 PHP >=5.3)
function array_reject(array &$arrayToFilter, callable $rejectCallback) {
$filteredArray = array();
foreach ($arrayToFilter as $key => $value) {
if (!$rejectCallback($value, $key)) {
$filteredArray[] = $value;
}
}
return $filteredArray;
}
因此,在我们当前的示例中,我们可以按如下方式使用上述函数:
$messages = [312, 401, 1599, 3, 6];
$messages = array_reject_value($messages, 401);
甚至更好:(因为这为我们提供了一种更好的语法,可以像 array_filter 一样使用)
$messages = [312, 401, 1599, 3, 6];
$messages = array_reject($messages, function ($value) {
return $value === 401;
});
上面可以用于更复杂的东西,比如假设我们要删除所有大于或等于 401 的值,我们可以简单地这样做:
$messages = [312, 401, 1599, 3, 6];
$greaterOrEqualThan = 401;
$messages = array_reject($messages, function ($value) use $greaterOrEqualThan {
return $value >= $greaterOrEqualThan;
});
我知道这根本没有效率,但简单、直观且易于阅读。因此,如果有人正在寻找一个不那么花哨的解决方案,它可以扩展为使用更多值或更具体的条件.. 这是一个简单的代码:
$result = array();
$del_value = 401;
//$del_values = array(... all the values you don`t wont);
foreach($arr as $key =>$value){
if ($value !== $del_value){
$result[$key] = $value;
}
//if(!in_array($value, $del_values)){
// $result[$key] = $value;
//}
//if($this->validete($value)){
// $result[$key] = $value;
//}
}
return $result
使用 or
运算符的单行:
($key = array_search($del_val, $messages)) !== false or unset($messages[$key]);
根据您的要求“每个值只能存在一次”,如果您只想在数组中保留唯一值,那么 array_unique()
可能就是您要寻找的。
输入:
$input = array(4, "4", "3", 4, 3, "3");
$result = array_unique($input);
var_dump($result);
结果:
array(2) {
[0] => int(4)
[2] => string(1) "3"
}
我认为最简单的方法是使用带有 foreach 循环的函数:
//This functions deletes the elements of an array $original that are equivalent to the value $del_val
//The function works by reference, which means that the actual array used as parameter will be modified.
function delete_value(&$original, $del_val)
{
//make a copy of the original, to avoid problems of modifying an array that is being currently iterated through
$copy = $original;
foreach ($original as $key => $value)
{
//for each value evaluate if it is equivalent to the one to be deleted, and if it is capture its key name.
if($del_val === $value) $del_key[] = $key;
};
//If there was a value found, delete all its instances
if($del_key !== null)
{
foreach ($del_key as $dk_i)
{
unset($original[$dk_i]);
};
//optional reordering of the keys. WARNING: only use it with arrays with numeric indexes!
/*
$copy = $original;
$original = array();
foreach ($copy as $value) {
$original[] = $value;
};
*/
//the value was found and deleted
return true;
};
//The value was not found, nothing was deleted
return false;
};
$original = array(0,1,2,3,4,5,6,7,4);
$del_val = 4;
var_dump($original);
delete_value($original, $del_val);
var_dump($original);
输出将是:
array(9) {
[0]=>
int(0)
[1]=>
int(1)
[2]=>
int(2)
[3]=>
int(3)
[4]=>
int(4)
[5]=>
int(5)
[6]=>
int(6)
[7]=>
int(7)
[8]=>
int(4)
}
array(7) {
[0]=>
int(0)
[1]=>
int(1)
[2]=>
int(2)
[3]=>
int(3)
[5]=>
int(5)
[6]=>
int(6)
[7]=>
int(7)
}
这是一个简单但可以理解的解决方案:
$messagesFiltered = [];
foreach ($messages as $message) {
if (401 != $message) {
$messagesFiltered[] = $message;
}
}
$messages = $messagesFiltered;
不定期副业成功案例分享
array_diff()
会比较慢,因为它是比较两个 数组,而不是像array_search()
那样简单地搜索一个。0
键或任何其他虚假值,则不会取消设置该值,并且您的代码将不起作用。您应该测试$key === false
。 (编辑-你明白了)