要素の設定を解除した後で配列キーをリベースする


183

私は配列を持っています:

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

配列の内容をダンプすると、次のようになります。

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

ループして特定のキーを設定解除すると、インデックスがすべてジャッキアップされます。

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

その後、今別のダンプを実行すると、次のようになります。

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

要素が再びゼロベースになるように配列をリセットする適切な方法はありますか?

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

回答:


411

これを試して:

$array = array_values($array);

array_values()の使用


6
+1。マニュアルには順序付けが維持されると明記されていないことに注意してください。しかし、それが維持されない理由はわかりません。
オービットの軽量レース、

16
はい、注文は確実に維持されます。並べ替えれば恐ろしい機能になるでしょう!:)
webbiedave

1
@webbiedave申し訳ありませんが、そうではありません。実際に配列を並べ替えます。非常に奇妙です。
FooBar 2014年

4
常に簡単で簡潔な解決策を模索します:)
Bruce Lim

1
これは、配列にすでに番号が付けられている場合は簡単な解決策ですが、HTMLフォームの一部のように、キーがテキストとして設定されている場合は機能しません。フォームからの出力を識別するために一意のキー値に依存している場合、以下の方法のいずれかがより適切に機能します。

17

別の興味深い方法を得た:

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

$array = array_merge($array); 

$ arrayキーがリセットされます。


13

array_splice代わりに使用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);

ここに作業サンプル


7
これは機能していません。スプライスは素晴らしいですが、呼び出しのたびにインデックスを再配置するため、for / foreachループ内では使用できません。したがって、foreachループのインデックスは、次の要素ではなく、その位置の要素を指します。再配置されたアレイ上。例では、値 '3'を削除し、値 '1'と '2'のみを削除する必要があるときに値 '2'を残していることがわかります
NotGaeL

1
@elcodedocle次に、foreachループを使用しないでください。標準i Loopを使用し、スプライス後にiをリセットするだけです。また、Working sample here.動作していません。
SpYk3HH 2014年

リンク切れ、修正できますか?
Michel Ayres、

5

単なる添加物です。

私はこれが古いことを知っていますが、自分で思いついたとは思えない解決策を追加したかったのです。別の解決策を探しているときにこの質問を見つけ、「まあ、私がここにいる間に」と気づきました。

まず、Nealの答えはループを実行した後に使用するのに適していますが、すべての作業を一度に実行することをお勧めします。もちろん、特定のケースでは、この単純な例よりも多くの作業を行わなければなりませんでしたが、この方法は依然として適用されます。他のカップルがforeachループを提案したところを見ましたが、獣の性質上、これは仕事の後でまだあなたを残します。通常foreach、のような単純なものをお勧めしますが、この場合、古き良き時代のfor loopロジックを覚えておくことをお勧めします。単に使用してiください!適切なインデックスを維持iするには、Arrayアイテムを削除するたびにから差し引くだけです。

これが私の簡単で実用的な例です:

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

出力されます:

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

これは多くの単純な実装を持つことができます。たとえば、私の正確なケースでは、多次元値に基づいて配列に最新のアイテムを保持する必要がありました。意味をお見せしましょう:

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

出力されます:

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

ご覧のとおり、現在のアイテムではなく以前のアイテムを削除しようとしているので、スプライスの前に$ iを操作します。


1

遅い答えですが、PHP 5.3以降はそうなる可能性があります。

$array = array(1, 2, 3, 4, 5);
$array = array_values(array_filter($array, function($v) {
    return !($v == 1 || $v == 2);
}));
print_r($array);

1

または、配列を参照渡しする独自の関数を作成することもできます。

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

だからあなたがしなければならないすべては...

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

...そして今、あなた$arrayはあなたが入れた値がなく$unsets、キーがリセットされています


1

100%私のために働いています!配列の要素を設定解除した後、これを使用して配列のインデックスを再作成できます

$result=array_combine(range(1, count($your_array)), array_values($your_array));

0

$arr = array_merge($arr); 配列のリベースに使用 します。シンプルでわかりやすい。


-2

私の状況では、配列値を持つ一意のキーを保持する必要があったため、2番目の配列を使用しました。

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

$arr2 = array();
foreach($arr1 as $key=>$value) $arr2[$key] = $value;
$arr1 = $arr2
unset($arr2);

1)unset($arr1)ループで反復することができないようにするあなた。2)最後から2行目のセミコロンがない。このコードスニペットは実行されません。
Rockin4Life33
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.