【问题标题】:How to rename object keys inside array如何重命名数组中的对象键
【发布时间】:2020-11-26 18:39:09
【问题描述】:

我有一个这样的对象数组:

const customers = [
  {
    customer_name: 'Negan', 
    customer_age: 45, 
    customer_weapon: 'Bat',
    customer_email: 'negan@sanctuary.com',
    customer_city: 'Washington' 
  },
  {
    customer_name: 'Daryl', 
    customer_age: 41, 
    customer_weapon: 'Crossbow',
    customer_email: 'daryl.dixon@kickass.com',
    customer_city: 'Atlanta' 
  },
  {
    customer_name: 'Rick', 
    customer_age: 45, 
    customer_weapon: 'Magnum 357',
    customer_email: 'rick@alexandria.com',
    customer_city: 'King County' 
  },
]

我想用这些键替换对象内的所有键:

const newKeys = [
   'firstname',
   'age',
   'weapon',
   'email',
   'city'
]

最好的方法是什么?一个例子将不胜感激!

【问题讨论】:

  • 您能告诉我们您的尝试吗?我们帮助纠正你的缺陷,而不是给你代码
  • 注意:每个人都应该知道这样一个事实,即任何仅基于替换键列表的方法实际上仅限于一种客户对象的键顺序(和结构)。环境始终必须确保每个客户对象的密钥创建顺序相同。

标签: javascript arrays object ecmascript-6


【解决方案1】:

我编写了这段代码来满足我对对象属性名称更改的所有需求。

deepRenameKeys = function(array: any[], shape: Object): any[] {
    if (!array || !array.length || !shape) return;
    return array.map(item => {
        let _obj = {};
        for (const key in shape) {
            if (shape.hasOwnProperty(key)) {
                _obj[key] = shape[key].split('.').length ?
                    shape[key].split('.').reduce((a, b) => a[b], item) :
                    item[shape[key]];
            }
        }
        return _obj;
    })
}

请注意,您也可以使用点分表示法:

const customers = [
    {
        customer_name: 'Negan',
        customer_age: 45,
        customer_weapon: {
            kind: 'Bat',
            type: 'melee'
        },
        customer_email: 'negan@sanctuary.com',
        customer_city: 'Washington'
    },
    {
        customer_name: 'Daryl',
        customer_age: 41,
        customer_weapon: {
            kind: 'Crossbow',
            type: 'range'
        },
        customer_email: 'daryl.dixon@kickass.com',
        customer_city: 'Atlanta'
    },
    {
        customer_name: 'Rick',
        customer_age: 45,
        customer_weapon: {
            kind: 'Magnum 357',
            type: 'range'
        },
        customer_email: 'rick@alexandria.com',
        customer_city: 'King County'
    }
];

const newKeys = [
    'firstname': 'customer_name',
    'age': 'customer_age',
    'weapon': 'customer_weapon.kind',
    'weaponType': 'customer_weapon.type'
    'email': 'customer_email',
    'city': 'customer_city'
];

let newData = deepRenameKeys(customers, newKeys);

【讨论】:

    【解决方案2】:

    另一个使用replace 的选项同时在字符串化的customers 中查找属性名称,然后解析回JSON:

    const customers = [
      {
        customer_name: 'Negan', 
        customer_age: 45, 
        customer_weapon: 'Bat',
        customer_email: 'negan@sanctuary.com',
        customer_city: 'Washington' 
      },
      {
        customer_name: 'Daryl', 
        customer_age: 41, 
        customer_weapon: 'Crossbow',
        customer_email: 'daryl.dixon@kickass.com',
        customer_city: 'Atlanta' 
      },
      {
        customer_name: 'Rick', 
        customer_age: 45, 
        customer_weapon: 'Magnum 357',
        customer_email: 'rick@alexandria.com',
        customer_city: 'King County' 
      },
    ]
    
    const newKeys = [
       {from: 'customer_name', to:'firstname'},
       {from: 'customer_age', to:'age'},
       {from: 'customer_weapon', to:'weapon'},
       {from: 'customer_email', to:'email'},
       {from: 'customer_city', to:'city'}
    ]
    
    
    let str = JSON.stringify(customers);
    
    newKeys.forEach(o=>str = str.replace(new RegExp(o.from, 'g'), o.to));
    
    console.log(JSON.parse(str));

    【讨论】:

      【解决方案3】:

      通过重命名使用解构

      const update = (arr) =>
        arr.map(
          ({
            customer_name: firstname,
            customer_age: age,
            customer_weapon: weapon,
            customer_email: email,
            customer_city: city,
          }) => ({
            firstname,
            age,
            weapon,
            email,
            city,
          })
        );
      
      const customers = [
        {
          customer_name: "Negan",
          customer_age: 45,
          customer_weapon: "Bat",
          customer_email: "negan@sanctuary.com",
          customer_city: "Washington",
        },
        {
          customer_name: "Daryl",
          customer_age: 41,
          customer_weapon: "Crossbow",
          customer_email: "daryl.dixon@kickass.com",
          customer_city: "Atlanta",
        },
        {
          customer_name: "Rick",
          customer_age: 45,
          customer_weapon: "Magnum 357",
          customer_email: "rick@alexandria.com",
          customer_city: "King County",
        },
      ];
      
      const newKeys = ["firstname", "age", "weapon", "email", "city"];
      
      console.log(update(customers));

      【讨论】:

        【解决方案4】:

        我强烈建议在简单的新键列表上使用键替换映射,因为后者在很大程度上取决于客户对象的键顺序。

        如果客户对象满足 1:1 键映射,请采用与此类似的方法,通过在每个迭代步骤中创建一个新客户对象来映射客户对象列表,通过减少每个迭代步骤的键元组列表元组持有新旧键...

        function createNewCustomerFromOldOneViaBoundConfig(customer) {
          return Object.entries(this).reduce((newCustomer, [key, newKey]) => {
        
            newCustomer[newKey] = customer[key];
            return newCustomer;
        
          }, {});
        };
        
        
        const customerKeyReplacementMap = {
          customer_name: 'firstname',
          customer_age: 'age',
          customer_weapon: 'weapon',
          customer_email: 'email',
          customer_city: 'city'
        };
        
        const customers = [{
        
          customer_name: 'Negan', 
          customer_age: 45, 
          customer_weapon: 'Bat',
          customer_email: 'negan@sanctuary.com',
          customer_city: 'Washington' 
        }, {
          customer_name: 'Daryl', 
          customer_age: 41, 
          customer_weapon: 'Crossbow',
          customer_email: 'daryl.dixon@kickass.com',
          customer_city: 'Atlanta' 
        }, {
          customer_name: 'Rick', 
          customer_age: 45, 
          customer_weapon: 'Magnum 357',
          customer_email: 'rick@alexandria.com',
          customer_city: 'King County'
        
        }].map(createNewCustomerFromOldOneViaBoundConfig, customerKeyReplacementMap);
        
        
        console.log('customers : ', customers);
        .as-console-wrapper { min-height: 100%!important; top: 0; }

        一旦至少有一个客户对象违反了其键的严格 1:1 映射,就必须改变创建改变新客户对象的方法从它过时的对应物。

        这个案例还证明,任何仅基于替换键列表的方法实际上都仅限于一种客户对象的键顺序(和结构)......

        function createNewCustomerFromOldOneAndMutateKeysViaBoundConfig(oldCustomer) {
          return Object.entries(this).reduce((customer, [oldKey, key]) => {
        
            customer[key] = customer[oldKey];
            delete customer[oldKey];
        
            return customer;
        
          }, Object.assign({}, oldCustomer));
        };
        
        
        const customerKeyReplacementMap = { 
          customer_name: 'firstname',
          customer_age: 'age',
          customer_weapon: 'weapon',
          customer_email: 'email',
          customer_city: 'city'
        };
        
        const customers = [{
        
          additional_key_1: 'FOO',
        
          customer_name: 'Negan', 
          customer_age: 45,
          
          additional_key_2: 'BAR',
        
          customer_weapon: 'Bat',
          customer_email: 'negan@sanctuary.com',
          customer_city: 'Washington' 
        }, {
          additional_key_1: 'BAZ',
        
          customer_name: 'Daryl', 
          customer_age: 41,
        
          additional_key_2: 'BIZ',
        
          customer_weapon: 'Crossbow',
          customer_email: 'daryl.dixon@kickass.com',
          customer_city: 'Atlanta' 
        }, {
          additional_key_1: 'FOOBAR',
        
          customer_name: 'Rick', 
          customer_age: 45,
        
          additional_key_2: 'BAZBIZ',
        
          customer_weapon: 'Magnum 357',
          customer_email: 'rick@alexandria.com',
          customer_city: 'King County'
        
        }].map(
          createNewCustomerFromOldOneAndMutateKeysViaBoundConfig,
          customerKeyReplacementMap
        );
        
        
        console.log('customers : ', customers);
        .as-console-wrapper { min-height: 100%!important; top: 0; }

        【讨论】:

          【解决方案5】:

          这种方式也可以。

          const customers = [
              {
                  customer_name: 'Negan',
                  customer_age: 45,
                  customer_weapon: 'Bat',
                  customer_email: 'negan@sanctuary.com',
                  customer_city: 'Washington'
              },
              {
                  customer_name: 'Daryl',
                  customer_age: 41,
                  customer_weapon: 'Crossbow',
                  customer_email: 'daryl.dixon@kickass.com',
                  customer_city: 'Atlanta'
              },
              {
                  customer_name: 'Rick',
                  customer_age: 45,
                  customer_weapon: 'Magnum 357',
                  customer_email: 'rick@alexandria.com',
                  customer_city: 'King County'
              },
          ]
          
          const newKeys = [
              'firstname',
              'age',
              'weapon',
              'email',
              'city'
          ]
          
          let newArr = []
          
          customers.map(c => {
              let obj = {}
              Object.values(c).map((v,i)=>{
                  obj[newKeys[i]] = v;
              })
              newArr.push(obj)
          })
          
          console.log(newArr)
          

          【讨论】:

            【解决方案6】:

            你可以做一个简单的地图。这样键的顺序就无关紧要了。

            const customers = [{
                customer_name: 'Negan',
                customer_age: 45,
                customer_weapon: 'Bat',
                customer_email: 'negan@sanctuary.com',
                customer_city: 'Washington'
              },
              {
                customer_name: 'Daryl',
                customer_age: 41,
                customer_weapon: 'Crossbow',
                customer_email: 'daryl.dixon@kickass.com',
                customer_city: 'Atlanta'
              },
              {
                customer_name: 'Rick',
                customer_age: 45,
                customer_weapon: 'Magnum 357',
                customer_email: 'rick@alexandria.com',
                customer_city: 'King County'
              },
            ]
            
            var updated = customers.map(customer => {
              const {
                customer_name,
                customer_age,
                customer_weapon,
                customer_email,
                customer_city
              } = customer;
            
              return {
                firstname: customer_name,
                age: customer_age,
                weapon: customer_weapon,
                email: customer_email,
                city: customer_city
              }
            });
            
            console.log(updated);

            【讨论】:

              【解决方案7】:

              映射 customers 数组,并为该数组中的每个对象迭代其键,并使用这些键将值添加到具有重命名属性名称的新对象中。这样你也可以避免改变原始对象。

              const customers = [
                { customer_name: 'Negan', customer_age: 45, customer_weapon: 'Bat', customer_email: 'negan@sanctuary.com', customer_city: 'Washington' },
                { customer_name: 'Daryl', customer_age: 41, customer_weapon: 'Crossbow', customer_email: 'daryl.dixon@kickass.com', customer_city: 'Atlanta' },
                { customer_name: 'Rick', customer_age: 45, customer_weapon: 'Magnum 357', customer_email: 'rick@alexandria.com', customer_city: 'King County' },
              ];
              
              const newKeys = [ 'firstname', 'age', 'weapon', 'email', 'city' ];
              
              const res = customers.map(obj => {
                const newObj = {};
                Object.keys(obj).forEach((k, i) => newObj[newKeys[i]] = obj[k]);
                return newObj;
              });
              
              console.log(res);
              .as-console-wrapper { max-height: 100% !important; top: 0; }

              更好的方法是使newKeys 成为一个将旧键映射到新键的对象。这样您就不必依赖对象中键的顺序。

              为此,只需将newKeys 更改为如下所示的对象:

              const newKeys = { 
                customer_name: 'firstname', 
                customer_age: 'age', 
                customer_weapon: 'weapon',
                customer_email: 'email',
                customer_city: 'city'
              };
              

              并将上述代码sn-p中.map()方法中的代码更改为

              const res = customers.map(obj => {
                const newObj = {};
                Object.keys(obj).forEach(k => newObj[newKeys[k]] = obj[k]);
                return newObj;
              });
              

              【讨论】:

              • @Milos ...在我看来,这应该是例外的答案,因为 Yousaf 的回答表明了对任何仅基于简单密钥替换列表而不是任何形式的密钥的方法的缺陷的认识替换映射。
              【解决方案8】:

              您可以尝试使用for...offor...in 循环:

              const customers = [
                {
                  customer_name: 'Negan', 
                  customer_age: 45, 
                  customer_weapon: 'Bat',
                  customer_email: 'negan@sanctuary.com',
                  customer_city: 'Washington' 
                },
                {
                  customer_name: 'Daryl', 
                  customer_age: 41, 
                  customer_weapon: 'Crossbow',
                  customer_email: 'daryl.dixon@kickass.com',
                  customer_city: 'Atlanta' 
                },
                {
                  customer_name: 'Rick', 
                  customer_age: 45, 
                  customer_weapon: 'Magnum 357',
                  customer_email: 'rick@alexandria.com',
                  customer_city: 'King County' 
                },
              ];
              const newKeys = [
                 'firstname',
                 'age',
                 'weapon',
                 'email',
                 'city'
              ]
              for(var o of customers){
                var index = 0;
                for(var k in o){
                  delete Object.assign(o, {[newKeys[index]]: o[k] })[k];
                  index++;
                }
              }
              console.log(customers);

              【讨论】:

                【解决方案9】:

                您可以使用Object.values() 检索值,然后使用array.reduce() 组合一个新对象:

                const customers = [
                  {
                    customer_name: 'Negan', 
                    customer_age: 45, 
                    customer_weapon: 'Bat',
                    customer_email: 'negan@sanctuary.com',
                    customer_city: 'Washington' 
                  },
                  {
                    customer_name: 'Daryl', 
                    customer_age: 41, 
                    customer_weapon: 'Crossbow',
                    customer_email: 'daryl.dixon@kickass.com',
                    customer_city: 'Atlanta' 
                  },
                  {
                    customer_name: 'Rick', 
                    customer_age: 45, 
                    customer_weapon: 'Magnum 357',
                    customer_email: 'rick@alexandria.com',
                    customer_city: 'King County' 
                  },
                ];
                
                const newKeys = [
                   'firstname',
                   'age',
                   'weapon',
                   'email',
                   'city'
                ];
                
                let result = customers.map(obj => 
                    Object.values(obj).reduce((acc, cur, i) => { 
                       acc[newKeys[i]] = cur; 
                       return acc; }, {}));
                
                console.log(result);

                【讨论】:

                  【解决方案10】:

                  您可以遍历对象,然后将每个属性的keys 更改为newKeys 中的属性:

                  const customers = [
                    {
                      customer_name: 'Negan', 
                      customer_age: 45, 
                      customer_weapon: 'Bat',
                      customer_email: 'negan@sanctuary.com',
                      customer_city: 'Washington' 
                    },
                    {
                      customer_name: 'Daryl', 
                      customer_age: 41, 
                      customer_weapon: 'Crossbow',
                      customer_email: 'daryl.dixon@kickass.com',
                      customer_city: 'Atlanta' 
                    },
                    {
                      customer_name: 'Rick', 
                      customer_age: 45, 
                      customer_weapon: 'Magnum 357',
                      customer_email: 'rick@alexandria.com',
                      customer_city: 'King County' 
                    },
                  ]
                  
                  const newKeys = [
                     'firstname',
                     'age',
                     'weapon',
                     'email',
                     'city'
                  ]
                  
                  for (let i = 0; i < customers.length; i++) {
                       let customer = customers[i];
                       let j = 0;
                       for(let p in customer){
                            customer[newKeys[j++]] = customer[p];
                            delete customer[p];
                       }
                  }
                  
                  console.log(customers);

                  【讨论】:

                    【解决方案11】:

                    两步:

                    1. 使用从现有键复制的值创建一个新键
                    2. 删除您刚刚从中复制值的键

                    工作示例:

                    let myCustomer = {
                      customer_name: 'Negan', 
                      customer_age: 45 
                    }
                    
                    myCustomer.firstname = myCustomer.customer_name;
                    myCustomer.age = myCustomer.customer_age;
                    
                    delete myCustomer.customer_name;
                    delete myCustomer.customer_age;
                    
                    console.log(myCustomer);

                    【讨论】:

                      猜你喜欢
                      • 2018-05-17
                      • 2021-05-20
                      • 2015-05-14
                      • 1970-01-01
                      • 1970-01-01
                      • 2021-12-14
                      • 1970-01-01
                      • 2020-06-02
                      • 2020-10-14
                      相关资源
                      最近更新 更多