假设我们有两个数组:

$array_1 = array(
  '0' => 'zero',
  '1' => 'one',
  '2' => 'two',
  '3' => 'three',
);

$array_2 = array(
  'zero'  => '0',
  'one'   => '1',
  'two'   => '2',
  'three' => '3',
);

现在,我想在每个数组的第三个元素后插入数组('sample_key' => 'sample_value')。我该怎么做呢?


当前回答

我需要一些可以在键之前,替换,之后插入的东西;如果没有找到目标键,则在数组的开头或结尾添加。默认是在键后插入。

新功能

/**
 * Insert element into an array at a specific key.
 *
 * @param array $input_array
 *   The original array.
 * @param array $insert
 *   The element that is getting inserted; array(key => value).
 * @param string $target_key
 *   The key name.
 * @param int $location
 *   1 is after, 0 is replace, -1 is before.
 *
 * @return array
 *   The new array with the element merged in.
 */
function insert_into_array_at_key(array $input_array, array $insert, $target_key, $location = 1) {
  $output = array();
  $new_value = reset($insert);
  $new_key = key($insert);
  foreach ($input_array as $key => $value) {
    if ($key === $target_key) {
      // Insert before.
      if ($location == -1) {
        $output[$new_key] = $new_value;
        $output[$key] = $value;
      }
      // Replace.
      if ($location == 0) {
        $output[$new_key] = $new_value;
      }
      // After.
      if ($location == 1) {
        $output[$key] = $value;
        $output[$new_key] = $new_value;
      }
    }
    else {
      // Pick next key if there is an number collision.
      if (is_numeric($key)) {
        while (isset($output[$key])) {
          $key++;
        }
      }
      $output[$key] = $value;
    }
  }
  // Add to array if not found.
  if (!isset($output[$new_key])) {
    // Before everything.
    if ($location == -1) {
      $output = $insert + $output;
    }
    // After everything.
    if ($location == 1) {
      $output[$new_key] = $new_value;
    }

  }
  return $output;
}

输入代码

$array_1 = array(
  '0' => 'zero',
  '1' => 'one',
  '2' => 'two',
  '3' => 'three',
);
$array_2 = array(
  'zero'  => '0',
  'one'   => '1',
  'two'   => '2',
  'three' => '3',
);

$array_1 = insert_into_array_at_key($array_1, array('sample_key' => 'sample_value'), 2, 1);
print_r($array_1);
$array_2 = insert_into_array_at_key($array_2, array('sample_key' => 'sample_value'), 'two', 1);
print_r($array_2);

输出

Array
(
    [0] => zero
    [1] => one
    [2] => two
    [sample_key] => sample_value
    [3] => three
)
Array
(
    [zero] => 0
    [one] => 1
    [two] => 2
    [sample_key] => sample_value
    [three] => 3
)

其他回答

你可以在foreach循环中插入元素,因为这个循环工作在原始数组的副本上,但是你必须跟踪插入的行数(在这段代码中我称之为“膨胀”):

$bloat=0;
foreach ($Lines as $n=>$Line)
    {
    if (MustInsertLineHere($Line))
        {
        array_splice($Lines,$n+$bloat,0,"string to insert");
        ++$bloat;
        }
    }

显然,您可以推广这种“膨胀”思想来处理foreach循环期间的任意插入和删除。

这是一种更好的方法,如何在数组的某个位置插入项目。

function arrayInsert($array, $item, $position)
{
    $begin = array_slice($array, 0, $position);
    array_push($begin, $item);
    $end = array_slice($array, $position);
    $resultArray = array_merge($begin, $end);
    return $resultArray;
}

我这样做


    $slightly_damaged = array_merge(
        array_slice($slightly_damaged, 0, 4, true) + ["4" => "0.0"], 
        array_slice($slightly_damaged, 4, count($slightly_damaged) - 4, true)
    );

不像Artefacto的答案那么具体,但基于他使用array_slice()的建议,我写了下一个函数:

function arrayInsert($target, $byKey, $byOffset, $valuesToInsert, $afterKey) {
    if (isset($byKey)) {
        if (is_numeric($byKey)) $byKey = (int)floor($byKey);
        $offset = 0;

        foreach ($target as $key => $value) {
            if ($key === $byKey) break;
            $offset++;
        }

        if ($afterKey) $offset++;
    } else {
        $offset = $byOffset;
    }

    $targetLength = count($target);
    $targetA = array_slice($target, 0, $offset, true);
    $targetB = array_slice($target, $offset, $targetLength, true);
    return array_merge($targetA, $valuesToInsert, $targetB);
}

特点:

插入一个或múltiple值 插入键值对 在键前/键后插入,或按偏移量插入

使用例子:

$target = [
    'banana' => 12,
    'potatoe' => 6,
    'watermelon' => 8,
    'apple' => 7,
    2 => 21,
    'pear' => 6
];

// Values must be nested in an array
$insertValues = [
    'orange' => 0,
    'lemon' => 3,
    3
];

// By key
// Third parameter is not applicable
//     Insert after 2 (before 'pear')
var_dump(arrayInsert($target, 2, null, $valuesToInsert, true));
//     Insert before 'watermelon'
var_dump(arrayInsert($target, 'watermelon', null, $valuesToInsert, false)); 

// By offset
// Second and last parameter are not applicable
//     Insert in position 2 (zero based i.e. before 'watermelon')
var_dump(arrayInsert($target, null, 2, $valuesToInsert, null)); 

这是一个老问题,但我在2014年发表了一篇评论,经常回到这个问题。我想我应该留下一个完整的答案。这不是最短的解决方案,但很容易理解。

在关联数组中插入一个新值,在有编号的位置,保留键并保持顺序。

$columns = array(
    'id' => 'ID',
    'name' => 'Name',
    'email' => 'Email',
    'count' => 'Number of posts'
);

$columns = array_merge(
    array_slice( $columns, 0, 3, true ),     // The first 3 items from the old array
    array( 'subscribed' => 'Subscribed' ),   // New value to add after the 3rd item
    array_slice( $columns, 3, null, true )   // Other items after the 3rd
);

print_r( $columns );

/*
Array ( 
    [id] => ID 
    [name] => Name 
    [email] => Email 
    [subscribed] => Subscribed 
    [count] => Number of posts 
)
*/