How to efficiently insert elements after another known (by key or pointer) element in a PHP array?

后端 未结 6 1978
萌比男神i
萌比男神i 2021-02-07 11:01

Given an array:

$a = array(
    \'abc\',
    123,
    \'k1\'=>\'v1\',
    \'k2\'=>\'v2\',
    78,
    \'tt\',
    \'k3\'=>\'v3\'
);

Wi

相关标签:
6条回答
  • 2021-02-07 11:35

    Generally speaking doubly linked list would be ideal for this task.

    There is a built-in implementation of that since PHP 5.3, called SplDoublyLinkedList and since PHP 5.5 it also has add method, which allows adding/inserting values in the middle.

    0 讨论(0)
  • 2021-02-07 11:46

    There's a nice function that would help you here: https://gist.github.com/scribu/588429

    0 讨论(0)
  • 2021-02-07 11:53

    You can't use internal array pointer to insert elements.

    There's array_splice which can insert/remove/replace elements and subarrays, but it's intended for integer-indexed arrays.

    I'm afraid you'll have to rebuild the array to insert element (except cases where you want to insert first/last element) or use separate integer-indexed array for holding keys in the order you want.

    0 讨论(0)
  • 2021-02-07 11:58

    You could do it by splitting your array using array_keys and array_values, then splice them both, then combine them again.

    $insertKey = 'k1';
    
    $keys = array_keys($arr);
    $vals = array_values($arr);
    
    $insertAfter = array_search($insertKey, $keys) + 1;
    
    $keys2 = array_splice($keys, $insertAfter);
    $vals2 = array_splice($vals, $insertAfter);
    
    $keys[] = "myNewKey";
    $vals[] = "myNewValue";
    
    $newArray = array_merge(array_combine($keys, $vals), array_combine($keys2, $vals2));
    
    0 讨论(0)
  • 2021-02-07 11:58

    I found a great answer here that works really well. I want to document it, so others on SO can find it easily:

    /*
     * Inserts a new key/value before the key in the array.
     *
     * @param $key
     *   The key to insert before.
     * @param $array
     *   An array to insert in to.
     * @param $new_key
     *   The key to insert.
     * @param $new_value
     *   An value to insert.
     *
     * @return
     *   The new array if the key exists, FALSE otherwise.
     *
     * @see array_insert_after()
     */
    function array_insert_before($key, array &$array, $new_key, $new_value) {
      if (array_key_exists($key, $array)) {
        $new = array();
        foreach ($array as $k => $value) {
          if ($k === $key) {
            $new[$new_key] = $new_value;
          }
          $new[$k] = $value;
        }
        return $new;
      }
      return FALSE;
    }
    
    /*
     * Inserts a new key/value after the key in the array.
     *
     * @param $key
     *   The key to insert after.
     * @param $array
     *   An array to insert in to.
     * @param $new_key
     *   The key to insert.
     * @param $new_value
     *   An value to insert.
     *
     * @return
     *   The new array if the key exists, FALSE otherwise.
     *
     * @see array_insert_before()
     */
    function array_insert_after($key, array &$array, $new_key, $new_value) {
      if (array_key_exists ($key, $array)) {
        $new = array();
        foreach ($array as $k => $value) {
          $new[$k] = $value;
          if ($k === $key) {
            $new[$new_key] = $new_value;
          }
        }
        return $new;
      }
      return FALSE;
    }
    
    0 讨论(0)
  • 2021-02-07 11:58

    This way is fine for new values without keys. You can not insert value with a key, and numeric indexes will be 'reset' as 0 to N-1.

    $keys = array_keys($a);
    $index = array_flip($keys);
    
    $key = key($a); //current element
    //or 
    $key = 'k1';
    
    array_splice($a, $index[$key] + 1, 0, array('value'));
    
    0 讨论(0)
提交回复
热议问题