首页 > 解决方案 > 更改包含对象数组的对象中的属性名称

问题描述

我目前处于一种情况,即我想将对象中的某些属性更改为蛇盒。目前,如果该对象中的属性不在嵌套对象或数组中的对象中,我可以更改它们的名称。这是我的函数以及我传入的对象:

/* an object to refer to where the values are what I want to change the name to */

const camelToSnake = {
  accountId: 'id',
  taxId: 'tax_id',
  individuals: 'customers',
  firstName: 'first_name',
  lastName: 'last_name',
};

/* example object I am passing in to the function */

const obj = {
  accountId: "12345",
  individuals: [
    {name: {firstName: "John", lastName: "Doe"}},
    {name: {firstName: "Bob", lastName: "Smith"}},
  ],
  taxId: "67890",
}

const restructureToSnakeCase = obj => {
  const newObj = {};
  Object.keys(obj).forEach(key => {
    if(typeof obj[key] === 'object'){
      restructureToSnakeCase(obj[key])
    }
    if(Array.isArray(obj[key])){
      obj[key].map(el => {
        restructureToSnakeCase(obj[key])
      })
    }
    newObj[camelToSnake[key] || key] = obj[key]    
  });
  return newObj;
};

到目前为止,使用我的函数,它能够遍历任何第一级对象并更改属性名称,但没有任何嵌套值。

我在上面传入的对象是结果:

{
  id: "12345",
  customers: [
   {name: {firstName: "John", lastName: "Doe"}},
   {name: {firstName: "Bob", lastName: "Smith"}},
  ],
  tax_id: "67890"
}

在这种情况下,“firstName”和“lastName”应该是“first_name”和“last_name”。

我认为通过上面的递归,它可以进入每个嵌套对象并相应地更改属性名称,但显然这不起作用。我真的很感激任何指示。

标签: javascriptarraysobjectrecursion

解决方案


您需要将递归调用的结果分配restructureToSnakeCasenewObj. 您还应该注意检查null(谁typeofobj),首先检查该值是否是一个数组(以便您可以检查.map它 - 否则,如果它是一个对象,只需执行一个普通的递归调用)。

/* an object to refer to where the values are what I want to change the name to */

const camelToSnake = {
  accountId: 'id',
  taxId: 'tax_id',
  individuals: 'customers',
  firstName: 'first_name',
  lastName: 'last_name',
};

/* example object I am passing in to the function */

const obj = {
  accountId: "12345",
  individuals: [
    {name: {firstName: "John", lastName: "Doe"}},
    {name: {firstName: "Bob", lastName: "Smith"}},
  ],
  taxId: "67890",
}

const restructureToSnakeCase = obj => {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }
  const newObj = {};
  Object.entries(obj).forEach(([key, val]) => {
    const newKey = camelToSnake[key] || key;
    if (Array.isArray(val)) {
      newObj[newKey] = val.map(restructureToSnakeCase)
    } else if (typeof val === 'object' && val !== null) {
      newObj[newKey] = restructureToSnakeCase(val)
    } else {
      newObj[newKey] = val;
    }
  });
  return newObj;
};
console.log(restructureToSnakeCase(obj));

我更喜欢使用Object.fromEntries,它看起来更干净:

/* an object to refer to where the values are what I want to change the name to */

const camelToSnake = {
  accountId: 'id',
  taxId: 'tax_id',
  individuals: 'customers',
  firstName: 'first_name',
  lastName: 'last_name',
};

/* example object I am passing in to the function */

const obj = {
  accountId: "12345",
  individuals: [
    {name: {firstName: "John", lastName: "Doe"}},
    {name: {firstName: "Bob", lastName: "Smith"}},
  ],
  taxId: "67890",
}

const restructureToSnakeCase = item => {
  if (typeof item !== 'object' || item === null) {
    return item;
  }
  if (Array.isArray(item)) {
    return item.map(restructureToSnakeCase);
  }
  return Object.fromEntries(
    Object.entries(item).map(([key, val]) => [
      camelToSnake[key] || key,
      restructureToSnakeCase(val)
    ])
  );
};

console.log(restructureToSnakeCase(obj));


推荐阅读