값으로 배열 항목 제거


166

주어진 값으로 배열 항목을 제거해야합니다.

if (in_array($id, $items)) {
    $items = array_flip($items);
    unset($items[ $id ]);
    $items = array_flip($items);
}

더 짧은 (보다 효율적인) 방식으로 수행 할 수 있습니까?


1
Ben

답변:


423

간단한 원 라이너로 달성 할 수 있습니다.

이 배열을 갖는 것 :

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

넌 할 수있어:

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

그리고 가치 $arr는 다음과 같습니다.

array('nice_item', 'another_liked_item')

그것이 아름다운 코드를 작성하는 데 도움이되기를 바랍니다.


2
아니, 하지 참조 배열과 작품의 array_diff함수는 새로운 배열을 반환, 비파괴입니다.
Alejandro García Iglesias

2
@srcspider 왜 안돼? $referenced = array_diff($referenced, $items_to_remove);
Alejandro García Iglesias

1
$ referenced는 이제 새 배열을 가리키고 있으며 변경하려는 배열에는 여전히 이전 값이 있습니다.
srcspider

2
잘 @srcspider, 당신은 여기에 다음 ... 무슨 일인지 말해 codepad.org/11ZhiFP0
알레한드로 가르시아 이글 레시아

1
내 잘못이야; . PHP의 변수 앨리어싱 비밀은 항상 이상 나를 여행>>
srcspider

37

두 번째 답변을 추가하고 있습니다. 다양한 방법을 시도하기 위해 빠른 벤치마킹 스크립트를 작성했습니다.

$arr = array(0 => 123456);
for($i = 1; $i < 500000; $i++) {
    $arr[$i] = rand(0,PHP_INT_MAX);
}

shuffle($arr);
$arr2 = $arr;
$arr3 = $arr;

/** 
 * Method 1 - array_search()
 */
$start = microtime(true);
while(($key = array_search(123456,$arr)) !== false) {
    unset($arr[$key]);
}
echo count($arr). ' left, in '.(microtime(true) - $start).' seconds<BR>';

/** 
 * Method 2 - basic loop
 */
$start = microtime(true);
foreach($arr2 as $k => $v) {
    if ($v == 123456) {
        unset($arr2[$k]);
    }
}
echo count($arr2). 'left, in '.(microtime(true) - $start).' seconds<BR>';

/** 
 * Method 3 - array_keys() with search parameter
 */
$start = microtime(true);
$keys = array_keys($arr3,123456);
foreach($keys as $k) {
    unset($arr3[$k]);
}
echo count($arr3). 'left, in '.(microtime(true) - $start).' seconds<BR>';

array_keys()선택적 검색 매개 변수가 지정된 세 번째 방법 은 지금까지 가장 좋은 방법 인 것 같습니다. 출력 예 :

499999 left, in 0.090957164764404 seconds
499999left, in 0.43156313896179 seconds
499999left, in 0.028877019882202 seconds

이것으로 판단하면 내가 사용할 솔루션은 다음과 같습니다.

$keysToRemove = array_keys($items,$id);
foreach($keysToRemove as $k) {
    unset($items[$k]);
}

array_search는 array_diff 메소드를 사용하는 것보다 훨씬 읽기 쉬운 코드라고 생각합니다. 찬성 투표는
kendepelchin

@zombat 주문이 결과와 관련이 있는지 궁금합니다. 셔플은 우리가 찾고있는 값을 앞이나 끝에 더 가깝게 넣을 수 있습니다. 그 외에 ... +1
General Redneck

31

어때요?

if (($key = array_search($id, $items)) !== false) unset($items[$key]);

또는 여러 값의 경우 :

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

이렇게하면 키 손실도 방지 할 수 있으며 이는 부작용입니다 array_flip().


1
$ id가 첫 번째 배열 요소 인 경우 작동하지 않습니다. if (($ key = array_search ($ id, $ items))! == false) unset ($ items [$ key]);
Marek

15

제거하는 방법 $rm_val에서$arr

unset($arr[array_search($rm_val, $arr)]);

8

가장 강력한 솔루션은 array_filter 하는 자체 필터링 기능을 정의 할 수 있습니다.

그러나 일부는 ... 그것은 조금 상황에서, 과잉 말할 수
간단foreach 배열을 통과하고 원하지 않는 항목을 제거 루프이면 충분합니다.

귀하의 경우 다음과 같은 것이 트릭을 수행해야합니다.

foreach ($items as $key => $value) {
    if ($value == $id) {
        unset($items[$key]);
        // If you know you only have one line to remove, you can decomment the next line, to stop looping
        //break;
    }
}

6

3
방금 설명서를 읽었으며 array_keys ()를 사용하여 값과 관련된 모든 키를 찾는 것이 좋습니다.
Savageman 2009

@Savageman-합의. 빠른 벤치 마크 array_keys()를 실행했으며이 array_search()작업 보다 성능이 더 좋은 것 같습니다 .
zombat

6

솔루션은 배열에 고유 한 값이있는 경우에만 작동합니다

보다:

<?php
$trans = array("a" => 1, "b" => 1, "c" => 2);
$trans = array_flip($trans);
print_r($trans);
?>

필요한 경우 루프에서 array_search로 더 좋은 방법을 설정하지 않을 수 있습니다 .


당신이 맞지만,이 특별한 경우에 나는 가치가 유일하다는 것을 확신합니다 :)
Marek

5

플립없이 :

<?php
foreach ($items as $key => $value) {
    if ($id === $value) {
        unset($items[$key]);
    }
}

5
function deleteValyeFromArray($array,$value)
{
   foreach($array as $key=>$val)
   {
      if($val == $value)
      {
         unset($array[$key]);
      }
   }
   return $array;
}

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.