简体   繁体   English

在php的foreach循环中更改关联数组的$key

[英]Change $key of associative array in a foreach loop in php

I have an array like this:我有一个这样的数组:

array(
    'firstName' => 'Joe',
    'lastName'  => 'Smith'
    )

I need to loop over every element in my array and in the end, the array should look like this:我需要遍历数组中的每个元素,最后,数组应如下所示:

array(
    'FirstName' => 'Joe',
    'LastName'  => 'Smith'
    )

Failed idea was:失败的想法是:

    foreach($array as $key => $value)
    {
        $key = ucfirst($key);
    }

This obviously will not work, because the array is not passed by reference.这显然行不通,因为数组不是通过引用传递的。 However, all these attempts also fail:然而,所有这些尝试也都失败了:

    foreach(&$array as $key => $value)
    {
        $key = ucfirst($key);
    }


    foreach($array as &$key => $value)
    {
        $key = ucfirst($key);
    }

Pretty much at my wits end with this one.几乎在我的智慧中结束了这一点。 I'm using Magento 1.9.0.1 CE, but that's pretty irrelevant for this problem.我使用的是 Magento 1.9.0.1 CE,但这与这个问题无关。 If you must know, the reason I have to do this is because I have a bunch of object that's I'm returning as an array to be assembled into a SOAP client.如果您必须知道,我必须这样做的原因是因为我有一堆对象,我将这些对象作为数组返回以组装到 SOAP 客户端。 The API I'm using requires the keys to begin with a capital letter...however, I don't wish to capitalize the first letter of my object's variable names.我使用的 API 要求键以大写字母开头……但是,我不希望将对象变量名的第一个字母大写。 Silly, I know, but we all answer to someone, and that someone wants it that way.傻,我知道,但我们都回答某人,有人想要那样。

unset it first in case it is already in the proper format, otherwise you will remove what you just defined:如果它已经是正确的格式,请先unset ,否则您将删除刚刚定义的内容:

foreach($array as $key => $value)
    {
        unset($array[$key]);
        $array[ucfirst($key)] = $value;
    }

You can't modify the keys in a foreach , so you would need to unset the old one and create a new one.您不能修改foreach的键,因此您需要取消设置旧键并创建一个新键。 Here is another way:这是另一种方式:

$array = array_combine(array_map('ucfirst', array_keys($array)), $array);
  1. Get the keys using array_keys使用array_keys获取密钥
  2. Apply ucfirst to the keys using array_map应用ucfirst使用键array_map
  3. Combine the new keys with the values using array_combine使用array_combine将新键与值array_combine

The answers here are dangerous, in the event that the key isn't changed, the element is actually deleted from the array.这里的答案很危险,如果键没有改变,元素实际上是从数组中删除的。 Also, you could unknowingly overwrite an element that was already there.此外,您可能会在不知不觉中覆盖已经存在的元素。

You'll want to do some checks first:你需要先做一些检查:

foreach($array as $key => $value)
{
    $newKey = ucfirst($key);

    // does this key already exist in the array?
    if(isset($array[$newKey])){
        // yes, skip this to avoid overwritting an array element!
        continue;
    }

    // Is the new key different from the old key?
    if($key === $newKey){
        // no, skip this since the key was already what we wanted.
        continue;
    }

    $array[$newKey] = $value;
    unset($array[$key]);
}

Of course, you'll probably want to combine these "if" statements with an "or" if you don't need to handle these situations differently.当然,如果您不需要以不同方式处理这些情况,您可能希望将这些“if”语句与“or”组合起来。

This might work:这可能有效:

foreach($array as $key => $value) {
     $newkey = ucfirst($key);
     $array[$newkey] = $value;
     unset($array[$key]);
}

but it is very risky to modify an array like this while you're looping on it.但是在循环时修改这样的数组是非常危险的。 You might be better off to store the unsettable keys in another array, then have a separate loop to remove them from the original array.您最好将不可设置的键存储在另一个数组中,然后使用单独的循环将它们从原始数组中删除。

And of course, this doesn't check for possible collisions in the aray, eg firstname -> FirstName , where FirstName already existed elsewhere in the array.当然,这不会检查数组中可能的冲突,例如firstname -> FirstName ,其中 FirstName 已经存在于数组中的其他地方。

But in the end, it boils down to the fact that you can't "rename" a key.但最终,归结为您无法“重命名”密钥的事实。 You can create a new one and delete the original, but you can't in-place modify the key, because the key IS the key to lookup an entry in the aray.您可以创建一个新的并删除原始的,但您不能就地修改键,因为键在数组中查找条目的键。 changing the key's value necessarily changes what that key is pointing at.更改键的值必然会更改该键所指向的内容。

Top of my head...我的头顶...

foreach($array as $key => $value){
    $newKey = ucfirst($key);
    $array[$newKey] = $value;
    unset($array[$key]);
}

Slightly change your way of thinking.稍微改变一下你的思维方式。 Instead of modifying an existing element, create a new one, and remove the old one.不要修改现有元素,而是创建一个新元素,然后删除旧元素。

If you use laravel or have Illuminate\\Support somewhere in your dependencies, here's a chainable way:如果您使用 laravel 或在您的依赖项中的某处有Illuminate\\Support ,这是一种可链接的方式:

>>> collect($array)
        ->keys()
        ->map(function ($key) {
            return ucfirst($key);
        })
        ->combine($array);

=> Illuminate\Support\Collection {#1389
     all: [
       "FirstName" => "Joe",
       "LastName" => "Smith",
     ],
   }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM