값으로 PHP 배열 삭제 (키 아님)


886

다음과 같이 PHP 배열이 있습니다.

$messages = [312, 401, 1599, 3, ...];

값이 포함 된 요소 $del_val(예 :)를 삭제하고 $del_val=401싶지만 키를 모르겠습니다. 도움이 될 수 있습니다. 각 값은 한 번만있을 수 있습니다 .

이 작업을 수행하는 가장 간단한 기능을 찾고 있습니다.


1
@Adam Strudwick 그러나이 배열에서 많은 삭제가있는 경우 한 번 반복하고 키를 값과 동일하게 만드는 것이 더 좋습니까?
dzona


가능한 PHP의
Alex

답변:


1566

사용 array_search()하고 unset, 다음을 시도하십시오

if (($key = array_search($del_val, $messages)) !== false) {
    unset($messages[$key]);
}

array_search()찾은 요소의 키를 반환합니다.이 키는를 사용하여 원래 배열에서 해당 요소를 제거하는 데 사용할 수 있습니다 unset(). FALSE실패시 리턴 되지만 성공시 false-y 값을 리턴 할 수 있습니다 ( 0예 : 키일 수 있음 ). 따라서 엄격한 비교 !==연산자가 사용됩니다.

if()문 여부를 확인합니다 array_search()값을 반환하고 한 경우에만 작업을 수행합니다.


14
$ messages = array_diff ($ messages, array ($ del_val))도 작동합니까? 성능이 더 좋을까요?
Adam Strudwick

9
@ 아담 왜 시험해 보지 않겠습니까? 내 느낌은 단순히 하나 를 검색하는 것이 아니라 배열을 비교할array_diff() 때 느려질 것 입니다. array_search()
Bojangles

22
이것이 유효하더라도 그러한 명령문에 값을 지정하지 않아야합니다. 문제가 생길뿐입니다.
adlawson

17
어떤 경우 $key이다 0?
evan

16
검색하는 값에 키 0또는 다른 잘못된 값이 있으면 값이 설정 해제되지 않고 코드가 작동하지 않습니다. 테스트해야합니다 $key === false. (편집-당신이 그것을 얻었다)
evan

671

배열에서 요소를 삭제하는 것은 기본적으로 하나의 요소와의 차이 를 설정 합니다.

array_diff( [312, 401, 15, 401, 3], [401] ) // removing 401 returns [312, 15, 3]

원하는 경우 동시에 원하는만큼 많은 요소를 제거 할 수 있습니다.

면책 조항 : 내 솔루션은 배열의 새로운 사본을 생성하면서 변경 된 수용 된 대답과 대조적으로 이전 배열을 그대로 유지합니다. 필요한 것을 선택하십시오.


32
이것은 문자열로 변환 될 수있는 객체에 대해서만 작동합니다.
nischayn22

7
에 대해 '구문 분석 오류'가 발생하는 것 같습니다 . 대신 [$element]사용 array($element)했습니다. 큰 문제는 아니지만 비슷한 문제가있는 사람이 혼자가 아니라는 것을 알기를 원했습니다.
Angad

8
물론, 나는 PHP 5.4가 대부분 이전 표기법을 버리는 것으로 가정했습니다. 발언 감사합니다.
Rok Kralj

22
어떤 이유로 든 예상대로 평등 조건으로 array_diff사용 한다는 점은 주목할 가치가 있습니다. @ nischayn22가 지적한 문제는 그 결과입니다. 임의의 요소 (객체 일 수도 있음)의 배열에서 작동하는 유틸리티 함수로 무언가를 사용하려면 Bojangle의 대답이 더 좋을 수 있습니다. (string) $elem1 === (string) $elem2$elem1 === $elem2
Mark Amery

4
또한이 메소드는 각 인수에 대해 내부적으로 정렬을 수행 array_diff()하므로 O (n)에서 최대 O (n lg n)까지 런타임을 이동시킵니다.
Ja͢ck

115

흥미로운 방법 중 하나는 다음을 사용하는 것입니다 array_keys().

foreach (array_keys($messages, 401, true) as $key) {
    unset($messages[$key]);
}

array_keys()함수는 특정 값에 대한 키와 엄격한 검사가 필요한지 여부를 비교하기 위해 두 개의 추가 매개 변수를 사용합니다 (예 : 비교에 === 사용).

또한 같은 값을 가진 여러 배열 항목을 제거 할 수도 있습니다 (예 :) [1, 2, 3, 3, 4].


3
@ blasteralfredΨ 선형 검색은 O (n)입니다. 왜 이것이 문제라고 생각하는지 모르겠습니다.
Ja͢ck

1
예, 여러 배열 항목 / 키를 선택하는 데 효과적입니다.
Oki Erie Rinaldi

3
모든 고유 값을 포함하지 않을 수있는 배열에 가장 적합합니다.
Derokorian

[0]-a, [2]-b ([1]은 사라졌지 만 배열은 여전히 ​​그리워집니다)
Rodniko

3
이 경우 @Rodniko도 필요 array_values()합니다. 나머지 키는 여전히 같은 순서로되어 있으므로 기술적으로 "정렬되지 않은"것은 아닙니다.
Ja͢ck

55

배열에 해당 값을 가진 요소가 하나만 포함된다는 것을 확실히 알고 있다면

$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);
});

참고 : 두 번째 옵션은 클로저가있는 PHP5.3 +에서만 작동합니다


41
$fields = array_flip($fields);
unset($fields['myvalue']);
$fields = array_flip($fields);

11
이것은 배열에 제거하려는 값 이외의 중복 값이 ​​포함되어 있지 않은 경우에만 작동합니다.
jberculo

2
@jberculo 그리고 때로는 정확히 당신이 필요로하는 경우도 있습니다. 어떤 경우에는 그 자체로 고유 한 배열을 수행하지 않아도됩니다
DarkMukke

어쩌면, 그러나 기본적으로 사용되고 다른 용도로 사용되는 함수의 운이 좋은 부작용이 아닌,이를 위해 특별히 설계된 함수를 사용하려고합니다. 또한 코드를 덜 투명하게 만듭니다.
jberculo

"각 값은 한 번만있을 수 있습니다"라는 메시지가 표시됩니다. 포스터가 smae 변수 이름을 사용하고 약간의 설명을 추가한다면 좋을 것입니다
Raatje

2
분명히 이것은 선택된 솔루션과 비교할 때 가장 빠릅니다. 작은 벤치마킹을했습니다.
AMB

28

다음 코드를 살펴보십시오.

$arr = array('nice_item', 'remove_me', 'another_liked_item', 'remove_me_also');

넌 할 수있어:

$arr = array_diff($arr, array('remove_me', 'remove_me_also'));

그리고 그것은 당신 에게이 배열을 얻을 것입니다 :

array('nice_item', 'another_liked_item')

1
연관 배열 위해 당신은 array_diff_assoc ()를 사용하는이
theCodeMachine

5
이 답변 과 다른 점은 무엇입니까?
random_user_name

26

가장 좋은 방법은 array_splice

array_splice($array, array_search(58, $array ), 1);

Best 이유는 http://www.programmerinterview.com/index.php/php-questions/how-to-delete-an-element-from-an-array-in-php/ 에 있습니다 .


4
예를 들어, 키에 틈이있는 연관 배열 및 배열에서는 작동하지 않습니다 [1, 2, 4 => 3].
Ja͢ck

죄송합니다. 작동합니다. 내가 제공 한 기사를 읽으십시오
Airy

4
그렇지 않습니다. 위의 주석 배열을 고려하십시오. 코드를 사용하여 값을 제거한 3후 배열은 다음과 같습니다 [1, 2, 3]. 즉, 값이 제거되지 않았습니다. 분명히, 나는 이것이 모든 시나리오에서 실패한다고 말하지는 않습니다.
Ja͢ck

1
array_splice가 가장 좋은 방법입니다. unset은 삭제 후 배열 인덱스를 조정하지 않습니다
Raaghu

21

또는 간단히 수동 방법 :

foreach ($array as $key => $value){
    if ($value == $target_value) {
        unset($array[$key]);
    }
}

어레이를 완전히 제어 할 수 있기 때문에 이것이 가장 안전합니다


1
array_splice()대신에 unset()를 사용 하면 배열 인덱스의 순서도 변경되므로이 경우 더 좋습니다.
Daniele Orlando

20

다음 코드에 따르면 반복 값이 $ messages에서 제거됩니다.

$messages = array_diff($messages, array(401));


3
투표권이 있습니다. 그것은 이미 다른 답변들 중 하나 였지만 당신은 간단하게 유지하면서 가장 잘 말합니다. 대답은 간단히 "array_diff"입니다.
ghbarratt

1
단순 해 보이지만 복잡성을 O (n)에서 O (n lg n)으로 변경합니다. 그래서, 그것은 사실 더 복잡하다)
르지 Przygoda

20

PHP 5.3+가있는 경우 한 줄 코드가 있습니다.

$array = array_filter($array, function ($i) use ($value) { return $i !== $value; }); 

확실해? 그 폐쇄에 대한 액세스 권한이없는 $value그래서 정말 당신이 액세스 할 수 있도록 미니 클래스에 투입되어야한다, $value... 폐쇄 내
random_user_name

@ cale_b, 예제를 업데이트했습니다. 또한 여기에 심판이 있습니다 : php.net/manual/en/functions.anonymous.php
David Lin

3
이것을 "한 줄 코드"라고 부르면 전체 코드베이스를 한 줄로 작성할 수도 있습니다.
Milan Simek

16
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 )


2
이 솔루션에 여러 함수 호출이 포함되어 있기 때문에 이것이 더 빠른지 확실하지 않습니다.
Julian Paolo Dayag

13

넌 할 수있어:

unset($messages[array_flip($messages)['401']]);

설명 : 401배열을 뒤집은 후 키가있는 요소를 삭제하십시오 .


상태를 보존하려면 매우주의해야합니다. 이후의 모든 코드에는 키 대신 값이 있어야하기 때문입니다.
saadlulu

1
array_flip ()은 원래 배열에 영향을 미치지 않으므로 @saadlulu $ messages 배열은 뒤집 히지 않으므로 이전 행을 적용한 후의 결과 배열은 원하지 않는 결과가 제거된다는 점을 제외하고 동일합니다.
Qurashi 2016 년

2
이것이 올바른지 확실하지 않으면 값이 401? 인 요소가 여러 개인 경우 어떻게해야 합니까?
Zippp

이것은 여전히 ​​키를 유지합니다.
Szabolcs Páll

8

여러 값을 삭제하려면 다음 중 하나를 시도하십시오.

while (($key = array_search($del_val, $messages)) !== false) 
{
    unset($messages[$key]);
}

6

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;
});

1
이 재창조 필터가 아닌가요? php.net/manual/en/function.array-filter.php
Richard Duerr

네 확실합니다. 이미 게시물에서 말했듯이 "또는 더 좋습니다 : (배열 필터와 같은 구문을 사용하면 더 좋습니다)". 때로는 함수를 밑줄로 거부해야하며 실제로 필터와 반대입니다 (가능한 한 적은 코드로 가져와야 함). 이것이 기능들이하는 일입니다. 이것은 값을 거부하는 간단한 방법입니다.
John Skoumbourdis

6
$array = array("apple", "banana",'mango');
$array = array_filter($array, function($v) { return $v != "apple"; });

이것을 시도하십시오, 이것은 값으로 요소를 제거하는 가장 빠르고 빠른 방법입니다


5

@Bojangles 답변이 도움이되었습니다. 감사합니다.

제 경우에는 배열이 연관 될 수도 있고 그렇지 않을 수도 있으므로 다음 함수를 추가했습니다.

function test($value, $tab) {

 if(($key = array_search($value, $tab)) !== false) {
    unset($tab[$key]); return true;

 } else if (array_key_exists($value, $tab)){
        unset($tab[$value]); return true;

 } else {
    return false; // the $value is not in the array $tab
 }

}

문안 인사


4

단일 라이너 코드 ( array_diff () 덕분에 ) 다음을 사용하십시오.

$messages = array_diff($messages, array(401));

4

허용되는 답변은 배열을 연관 배열로 변환하므로 허용 된 답변과 함께 비 연관 배열로 유지하려면 array_values너무 사용해야 할 수도 있습니다 .

if(($key = array_search($del_val, $messages)) !== false) {
    unset($messages[$key]);
    $arr = array_values($messages);
}

참조는 여기


4

배열에 고유 한 값을 유지하는 데 관심이 있다면 " 각 값은 한 번만있을 수 있습니다 "라는 요구 사항에 따라 원하는 값 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"
}

4

삭제하려는 값이 배열에 있거나 배열에있을 수있는 경우 array_diff 함수를 사용하십시오 . 이런 것들에 잘 작동하는 것 같습니다.

array_diff

$arrayWithValuesRemoved = array_diff($arrayOfData, $arrayOfValuesToRemove);

1
이 답변 과 다른 점은 무엇입니까?
random_user_name

4

나는 이것이 효율적이지 않지만 간단하고 직관적이며 읽기 쉽다는 것을 알고 있습니다.
따라서 누군가가 더 많은 가치 또는 더 구체적인 조건으로 작동하도록 확장 될 수있는 그렇게 화려하지 않은 솔루션을 찾고 있다면 .. 여기 간단한 코드가 있습니다.

$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

4

로 배열 키를 가져옵니다 array_search().


2
IF 값을 array_search에서 찾은 경우에만 어떻게 삭제합니까?
Adam Strudwick

3
$ k = array_search ($ needle, $ haystack, true); if ($ k! == false) {unset ($ haystack [$ k]); }
evan

3

키를 모른다면 중요하지 않다는 것을 의미합니다.

값을 키로 배치 할 수 있습니다. 즉, 값을 즉시 찾을 수 있습니다. 모든 요소에서 검색을 반복해서 사용하는 것보다 낫습니다.

$messages=array();   
$messages[312] = 312;    
$messages[401] = 401;   
$messages[1599] = 1599;   
$messages[3] = 3;    

unset($messages[3]); // no search needed

문자열로 변환 할 수있는 객체에만 작동합니다.
Emile Bergeron

2

or연산자를 사용하는 원 라이너 :

($key = array_search($del_val, $messages)) !== false or unset($messages[$key]);

2

URL을 참조 할 수 있습니다 : 기능

array-diff-key()

<?php
$array1 = array('blue'  => 1, 'red'  => 2, 'green'  => 3, 'purple' => 4);
$array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan'   => 8);

var_dump(array_diff_key($array1, $array2));
?>

그런 다음 출력은

array(2) {
  ["red"]=>
  int(2)
  ["purple"]=>
  int(4)
}


1

가장 간단한 방법은 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)
}

1

화살표 기능을 사용하는 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));
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.