Rebase chaves da matriz após a remoção de elementos

183

Eu tenho uma matriz:

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

Se eu fosse despejar o conteúdo da matriz, eles ficariam assim:

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

Quando eu percorrer e desmarcar determinadas teclas, o índice será aumentado.

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

Posteriormente, se eu fizesse outro despejo agora, ficaria assim:

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

Existe uma maneira adequada de redefinir a matriz para que seus elementos sejam baseados em zero novamente?

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

Respostas:

411

Tente o seguinte:

$array = array_values($array);

Usando array_values ​​()

Naftali tcp Neal
fonte
6
+1. Observo que o manual não declara explicitamente que a solicitação será mantida, mas não consigo ver por que não seria.
Lightness Races in Orbit -
16
Sim, o pedido é definitivamente mantido. Seria uma função hedionda se a reordenasse! :)
webbiedave
1
@webbiedave desculpe, mas isso não é verdade. Ele realmente reorganiza minha matriz. Muito, muito estranho
FooBar
4
sempre ir para as soluções concisas fáceis :)
Bruce Lim
1
Embora essa seja uma solução fácil quando a matriz já está numerada, ela não funciona quando a chave é definida como texto, como se fosse parte de um formulário HTML. Se você estiver confiando em valores-chave exclusivos para identificar a saída de um formulário, um dos métodos abaixo funcionará melhor.
17

Tem outro método interessante:

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

$array = array_merge($array); 

Agora as chaves $ array são redefinidas.

Web_Developer
fonte
13

Use em array_splicevez de 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);

Amostra de trabalho aqui .

Demian Brecht
fonte
7
Isto não está a funcionar. a emenda seria incrível, mas você não pode usá-lo dentro de um loop for / foreach porque ele reorganiza o índice toda vez que você o chama, portanto, o índice do loop foreach não aponta para o próximo elemento, mas para o elemento com essa posição na matriz reorganizada. Você pode ver em você exemplo, você está excluindo o valor '3' e deixando o valor '2' quando você deveria estar excluindo apenas os valores '1' e '2'
NotGaeL
1
@elcodedocle Então não use um foreachloop. Use o padrão i Loope simplesmente redefina i após uma emenda. Além disso, Working sample here.não está funcionando.
SpYk3HH
Link quebrado, você pode consertar?
Michel Ayres
5

Apenas um aditivo.

Sei que isso é antigo , mas eu queria adicionar uma solução que não vejo que me propusesse. Encontrei essa pergunta enquanto procurava uma solução diferente e imaginei: "Bem, enquanto estou aqui".

Antes de tudo, a resposta de Neal é boa e ótima de usar depois de executar seu loop, no entanto, eu prefiro fazer todo o trabalho de uma só vez. Obviamente, no meu caso específico, tive que fazer mais trabalho do que este exemplo simples aqui, mas o método ainda se aplica. Eu vi onde alguns outros sugeriram foreachloops, no entanto, isso ainda deixa você depois do trabalho devido à natureza da besta. Normalmente, sugiro coisas mais simples como foreach, no entanto, neste caso, é melhor lembrar boas for looplógicas antiquadas . Basta usar i! Para manter o índice apropriado, basta subtrair dei após cada remoção de um item da matriz.

Aqui está meu exemplo simples e prático :

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

Saída:

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

Isso pode ter muitas implementações simples. Por exemplo, meu caso exato exigia a retenção do item mais recente na matriz com base em valores multidimensionais. Eu vou te mostrar o que eu quero dizer:

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

Saída:

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"
        }
}

Como você vê, eu manipulo $ i antes da emenda, procurando remover o item anterior, e não o presente.

SpYk3HH
fonte
1

Resposta tardia, mas, depois do PHP 5.3, pode ser;

$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
fonte
1

Ou você pode criar sua própria função que passa a matriz por referência.

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

Então tudo o que você precisa fazer é ...

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

... e agora você $arrayestá sem os valores inseridos $unsetse as chaves são redefinidas

cheio
fonte
1

100% trabalhando para mim! Após desarmar elementos na matriz, você pode usá-lo para reindexar a matriz

$result=array_combine(range(1, count($your_array)), array_values($your_array));
Atta Ur Rehman
fonte
0

Eu uso $arr = array_merge($arr); para rebase uma matriz. Simples e direto.

Rockin4Life33
fonte
-2

Na minha situação, eu precisava reter chaves exclusivas com os valores da matriz, então apenas usei uma segunda matriz:

$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
fonte
1) Você, unset($arr1)que o tornará NÃO disponível para repetir no seu loop. 2) Falta o ponto e vírgula na penúltima linha. Este trecho de código não será executado.
Rockin4Life33