Odłóż klucze tablicy po rozbrojeniu elementów

183

Mam tablicę:

$array = array(1,2,3,4,5);

Gdybym zrzucił zawartość tablicy, wyglądałyby tak:

array(5) {
  [0] => int(1)
  [1] => int(2)
  [2] => int(3)
  [3] => int(4)
  [4] => int(5)
}

Kiedy przechodzę przez pętlę i rozbrajam określone klawisze, indeks zostaje podniesiony.

foreach($array as $i => $info)
{
  if($info == 1 || $info == 2)
  {
    unset($array[$i]);
  }
}

Następnie, jeśli zrobiłbym teraz kolejny zrzut, wyglądałoby to tak:

array(3) {
  [2] => int(3)
  [3] => int(4)
  [4] => int(5)
}

Czy istnieje właściwy sposób na zresetowanie tablicy, aby elementy były ponownie zerowane?

array(3) {
  [0] => int(3)
  [1] => int(4)
  [2] => int(5)
}
TuK
źródło

Odpowiedzi:

411

Spróbuj tego:

$array = array_values($array);

Korzystanie z array_values ​​()

Naftali alias Neal
źródło
6
+1. Zwracam uwagę, że instrukcja nie określa wprost, że kolejność zostanie utrzymana, ale nie rozumiem, dlaczego tak się nie stanie.
Wyścigi lekkości na orbicie
16
Tak, zamówienia są zdecydowanie utrzymane. Byłoby ohydną funkcją, gdyby ją zmieniła! :)
webbiedave
1
@webbiedave przepraszam, ale to nieprawda. To faktycznie zmienia kolejność mojej tablicy. Bardzo, bardzo dziwne.
FooBar
4
zawsze wybieraj proste zwięzłe rozwiązania :)
Bruce Lim
1
Chociaż jest to łatwe rozwiązanie, gdy tablica jest już numerowana, nie działa, gdy klucz jest ustawiony jako tekst, tak jakby był częścią formularza HTML. Jeśli korzystasz z unikatowych wartości klucza w celu identyfikacji danych wyjściowych z formularza, jedna z poniższych metod działa lepiej.
17

Mam inną interesującą metodę:

$array = array('a', 'b', 'c', 'd'); 
unset($array[2]); 

$array = array_merge($array); 

Teraz klucze tablicy $ zostały zresetowane.

Web Developer
źródło
13

Użyj array_splicezamiast unset:

$array = array(1,2,3,4,5);
foreach($array as $i => $info)
{
  if($info == 1 || $info == 2)
  {
    array_splice($array, $i, 1);
  }
}

print_r($array);

Próbka robocza tutaj .

Demian Brecht
źródło
7
To nie działa. splot byłby świetny, ale nie można go użyć w pętli for / foreach, ponieważ zmienia on indeks za każdym razem, gdy go wywołujesz, więc indeks pętli foreach nie wskazuje na następny element, ale na element o tej pozycji na przestawionej tablicy. W swoim przykładzie widać, że usuwasz wartość „3” i pozostawiasz wartość „2”, kiedy powinieneś usuwać tylko wartości „1” i „2”
NotGaeL
1
@elcodedocle Więc nie używaj foreachpętli. Użyj standardu i Loopi po prostu zresetuj i po spawaniu. Również Working sample here.nie działa.
SpYk3HH
Uszkodzony link, możesz to naprawić?
Michel Ayres
5

Po prostu dodatek.

Wiem, że to stare , ale chciałem dodać rozwiązanie. Nie widzę, że sam wymyśliłem. Znalazłem to pytanie podczas poszukiwania innego rozwiązania i po prostu pomyślałem: „Cóż, póki tu jestem”.

Przede wszystkim odpowiedź Neala jest dobra i świetna do użycia po uruchomieniu pętli, jednak wolę wykonywać całą pracę na raz. Oczywiście w moim konkretnym przypadku musiałem wykonać więcej pracy niż ten prosty przykład tutaj, ale metoda nadal obowiązuje. Widziałem, gdzie kilka innych sugerowało foreachpętle, jednak nadal pozostawia to po pracy ze względu na naturę bestii. Zwykle sugeruję prostsze rzeczy foreach, ale w tym przypadku najlepiej pamiętać staroświecką for looplogikę. Po prostu użyj i! Aby zachować odpowiedni indeks, po prostu odejmij ipo każdym usunięciu elementu Array.

Oto mój prosty, działający przykład:

$array = array(1,2,3,4,5);

for ($i = 0; $i < count($array); $i++) {
    if($array[$i] == 1 || $array[$i] == 2) {
        array_splice($array, $i, 1);
        $i--;
    }
}

Wyjdzie:

array(3) {
    [0]=> int(3)
    [1]=> int(4)
    [2]=> int(5)
}

Może to mieć wiele prostych implementacji. Na przykład mój dokładny przypadek wymagał przechowywania najnowszego elementu w tablicy na podstawie wartości wielowymiarowych. Pokażę ci, co mam na myśli:

$files = array(
    array(
        'name' => 'example.zip',
        'size' => '100000000',
        'type' => 'application/x-zip-compressed',
        'url' => '28188b90db990f5c5f75eb960a643b96/example.zip',
        'deleteUrl' => 'server/php/?file=example.zip',
        'deleteType' => 'DELETE'
    ),
    array(
        'name' => 'example.zip',
        'size' => '10726556',
        'type' => 'application/x-zip-compressed',
        'url' => '28188b90db990f5c5f75eb960a643b96/example.zip',
        'deleteUrl' => 'server/php/?file=example.zip',
        'deleteType' => 'DELETE'
    ),
    array(
        'name' => 'example.zip',
        'size' => '110726556',
        'type' => 'application/x-zip-compressed',
        'deleteUrl' => 'server/php/?file=example.zip',
        'deleteType' => 'DELETE'
    ),
    array(
        'name' => 'example2.zip',
        'size' => '12356556',
        'type' => 'application/x-zip-compressed',
        'url' => '28188b90db990f5c5f75eb960a643b96/example2.zip',
        'deleteUrl' => 'server/php/?file=example2.zip',
        'deleteType' => 'DELETE'
    )
);

for ($i = 0; $i < count($files); $i++) {
    if ($i > 0) {
        if (is_array($files[$i-1])) {
            if (!key_exists('name', array_diff($files[$i], $files[$i-1]))) {
                if (!key_exists('url', $files[$i]) && key_exists('url', $files[$i-1])) $files[$i]['url'] = $files[$i-1]['url'];
                $i--;
                array_splice($files, $i, 1);
            }
        }
    }
}

Wyjdzie:

array(1) {
    [0]=> array(6) {
            ["name"]=> string(11) "example.zip"
            ["size"]=> string(9) "110726556"
            ["type"]=> string(28) "application/x-zip-compressed"
            ["deleteUrl"]=> string(28) "server/php/?file=example.zip"
            ["deleteType"]=> string(6) "DELETE"
            ["url"]=> string(44) "28188b90db990f5c5f75eb960a643b96/example.zip"
        }
    [1]=> array(6) {
            ["name"]=> string(11) "example2.zip"
            ["size"]=> string(9) "12356556"
            ["type"]=> string(28) "application/x-zip-compressed"
            ["deleteUrl"]=> string(28) "server/php/?file=example2.zip"
            ["deleteType"]=> string(6) "DELETE"
            ["url"]=> string(45) "28188b90db990f5c5f75eb960a643b96/example2.zip"
        }
}

Jak widzisz, manipuluję $ i przed połączeniem, próbując usunąć poprzedni, a nie obecny przedmiot.

SpYk3HH
źródło
1

Późna odpowiedź, ale po PHP 5.3 może tak być;

$array = array(1, 2, 3, 4, 5);
$array = array_values(array_filter($array, function($v) {
    return !($v == 1 || $v == 2);
}));
print_r($array);
K-Gun
źródło
1

Lub możesz stworzyć własną funkcję, która przekazuje tablicę przez odniesienie.

function array_unset($unsets, &$array) {
  foreach ($array as $key => $value) {
    foreach ($unsets as $unset) {
      if ($value == $unset) {
        unset($array[$key]);
        break;
      }
    }
  }
  $array = array_values($array);
}

Więc wszystko, co musisz zrobić, to ...

$unsets = array(1,2);
array_unset($unsets, $array);

... a teraz $arraynie ma wartości, które umieściłeś, $unsetsa klucze zostały zresetowane

żartobliwy
źródło
1

100% pracuje dla mnie! Po rozbrojeniu elementów w tablicy możesz użyć tego do ponownego indeksowania tablicy

$result=array_combine(range(1, count($your_array)), array_values($your_array));
Atta Ur Rehman
źródło
0

Używam $arr = array_merge($arr); do zmiany podstawy tablicy. Prosty i bezpośredni.

Rockin4Life33
źródło
-2

W mojej sytuacji musiałem zachować unikalne klucze z wartościami tablic, więc właśnie użyłem drugiej tablicy:

$arr1 = array("alpha"=>"bravo","charlie"=>"delta","echo"=>"foxtrot");
unset($arr1);

$arr2 = array();
foreach($arr1 as $key=>$value) $arr2[$key] = $value;
$arr1 = $arr2
unset($arr2);
John K.
źródło
1) Ty, unset($arr1)który sprawi, że NIE będzie można iterować w pętli. 2) Brakuje średnika w wierszu od drugiego do ostatniego. Ten fragment kodu nie będzie działać.
Rockin4Life33