PHP难题:如何将项插入到一个关联数组中?

PHP难题:如何将项插入到一个关联数组中?,php,arrays,Php,Arrays,是的,这是一个有点诡计的问题一个数组(无副本),与任何奇数数组相反。让我解释一下,让我们从这里开始 $a = array ( 'one' => 1, 'two' => 2, 'three' => 3, 'four' => 4, 'five' => 5, 'six' => 6 ) ; 假设这个数组很长,超过100长。我一步一步地循环它,但在某个时刻(让我们在第二项中弥补这一点)发生了一些事情。也许数据有点古怪。然而,我们需要添加一些项目到它以供以后处理,然后在

是的,这是一个有点诡计的问题一个数组(无副本),与任何奇数数组相反。让我解释一下,让我们从这里开始

$a = array ( 'one' => 1, 'two' => 2, 'three' => 3, 'four' => 4, 'five' => 5, 'six' => 6 ) ;
假设这个数组很长,超过100长。我一步一步地循环它,但在某个时刻(让我们在第二项中弥补这一点)发生了一些事情。也许数据有点古怪。然而,我们需要添加一些项目到它以供以后处理,然后在不丢失当前位置的情况下继续循环。基本上,我想做这样的事情

echo current ( $a ) ;  // 'two'
array_insert ( $a, 'four', 'new_item', 100 ) ;
echo current ( $a ) ;  // 'two'
数组插入的定义是($array,$key,$where,$new,$new,$value);当然,$new_键和$new_值应该包装在数组包装器中,但这不是重点。下面是我希望看到的在上述代码运行之后发生的事情

print_r ( $a ) ; // array ( 'one' => 1, 'two' => 2, 'three' => 3, 'four' => 4, 'new_item' => 100, 'five' => 5, 'six' => 6 ) ;
echo current ( $a ) ;  // 'two'
无论何时使用阵列拼接、阵列切片、阵列推送或大多数其他阵列摆弄功能,基本上都会创建阵列的副本,然后可以将其复制回,但这会中断对原始阵列和位置的引用,上面的“我的循环”也会中断。我可以使用直接引用(即,
$a['new_item']='which;
)或将其放在末尾,但这些都不会将项目插入给定位置

$events = array_keys($a);
for ($i=0; $i < count($events); ++$i) {
    ...
    /* if there's an event to add after $j */
    array_splice($events, $j+1, 0, array($new_event_key));
    $a[$new_event_key] = $new_event_data;
    ...
}
有人要吗?如何直接(在其他地方处理的)向关联数组中进行真正的插入?到目前为止,我唯一的解决办法是

  • 记录位置(
    current()
  • 进行拼接/插入(阵列\切片)
  • 用新($old=$new)覆盖旧数组
  • 搜索新位置(首先重置(),然后循环查找[!!!!!!!])

  • 确实有更好、更简单、更优雅的方式来做一些目前步履蹒跚、沉重、步履蹒跚的事情吗?为什么没有一个数组\u set\u position($key)函数可以快速解决这个问题,或者没有一个数组\u insert可以直接在同一个数组(或两者)上工作?

    也许我没有正确地理解你,但你已经研究过了吗

    这可能也会引起你的兴趣


    你喜欢这个工作吗

    function array_insert($input, $key, $value)
    {
        if (($key = array_search($key, array_keys($input))) !== false)
        {
            return array_splice($input, $key, 1, $value);
        }
    
        return $input;
    }
    


    这是我能想到的最好的办法:

    $a = array
    (
        'one' => 1,
        'two' => 2,
        'three' => 3,
        'four' => 4,
        'five' => 5,
        'six' => 6,
    );
    
    ph()->Dump(next($a)); // 2
    array_insert($a, 'four', array('new_item' => 100));
    ph()->Dump(current($a)); // 2
    
    function array_insert(&$array, $key, $data)
    {
        $k = key($array);
    
        if (array_key_exists($key, $array) === true)
        {
            $key = array_search($key, array_keys($array)) + 1;
            $array = array_slice($array, null, $key, true) + $data + array_slice($array, $key, null, true);
    
            while ($k != key($array))
            {
                next($array);
            }
        }
    }
    
    ph()->Dump($a);
    
    /*
    Array
    (
        [one] => 1
        [two] => 2
        [three] => 3
        [four] => 4
        [new_item] => 100
        [five] => 5
        [six] => 6
    )
    */
    

    我认为不可能设置数组内部指针。

    与其使用关联数组作为事件队列,不如保留一个单独的整数索引数组。在显式索引变量上循环,而不是使用内部数组位置

    $events = array_keys($a);
    for ($i=0; $i < count($events); ++$i) {
        ...
        /* if there's an event to add after $j */
        array_splice($events, $j+1, 0, array($new_event_key));
        $a[$new_event_key] = $new_event_data;
        ...
    }
    
    $events=array\u key($a);
    对于($i=0;$i

    为了使事情更加连贯,您可以将这两个数组打包到一个事件队列类中。

    您能保证要添加的项目位于当前位置之后吗?如果没有,那么它无论如何都不会被处理。听起来你最好使用Ed,是的,这是一个恰当的观点。大多数情况下,这是我正在迭代的一个堆栈,堆栈上的早期事件可能会添加要稍后运行的事件。samshull,不确定您如何看待它的用法?Array_map在这些项上迭代并运行函数,但不会改变数组中的项数,是吗?好吧,我已经完成了,除了Z_ARRVAL_PP实现(在源文件中的这个注释附近;“/**这就是神奇发生的地方。*/”:)Brilliant.Hmm之外,没有什么可以改进的地方,它不能保持数组的(内部)位置不变,所以我仍然需要重置和搜索/设置它,不是吗?我对实际的拼接并没有问题,只是提供的所有拼接都会破坏内部计数器,迫使我处理相当昂贵的手动操作。@AlexanderJohannesen:是的,我想我不完全理解你的问题。你能发布一些虚拟数据和相应的代码/输出吗?@Alix,是的,好的,我已经更新了问题。也许更多的是关于更好地使用键查找和设置数组位置的问题…:)@亚历山大·约翰森:明白了。我看不出有什么办法,但让我考虑一下。@AlexanderJohannesen:我刚刚意识到我提出的代码正是你描述的算法。。。无论如何,这似乎是不可能的,因为
    array\u set\u position()
    ::,等等……是的,这是一种方法,尽管我的应用程序在其他方面依赖按键。也许它需要拆分,留下更多的序列化工作要做,但也许没有更好的方法?嗯。@Alexander:如果内置的数据结构不能满足您的需求,那么您最好实现自己的数据结构。使用事件队列类,可以实现和接口。它将起到阵列的作用,但会让您更好地控制定位。您甚至可以添加方法来获取和设置位置(可能使用)。是的,当然,我开始这样学习。首先,我将了解阵列上的插入/寻道操作有多昂贵,如果证明不好,我将严格执行该操作。:)看起来带内部指针的hashmap至少有一种按键设置指针的方法,但我可能必须在im上执行所有OO操作,以使其足够快。