【问题标题】:Maintaining order of items in the map function: Javascript维护地图功能中项目的顺序:Javascript
【发布时间】:2020-09-04 07:37:14
【问题描述】:

我正在尝试使用地图更改字段名称之一,但我看到项目的顺序正在改变。

var arrOfObj = [
  {
    name: "test1",
    value: "value1"
  },
  {
    name: "test2",
    value: "value2"
  }
];

function changeKeyName(arr, oldValue, newVal) {
  return arr.map(item => {
    item[`${newVal}`] = item[`${oldValue}`];
    delete item[`${oldValue}`];
    return item;
  });
}

console.log(changeKeyName(arrOfObj, "name", "type"));

有什么方法可以在更改其中一个字段名称的同时保持项目的顺序。

O/P:

[{type:"test1",value: "value1"}, {type: "test2", value:"value2"}]

提前致谢

【问题讨论】:

  • 我无法复制。 test1 保留数组中的第一项,test2 保留第二项。
  • 另外,您的“O/P”在两个对象之间缺少 },{
  • 不能设置对象键的顺序。
  • @GetOffMyLawn 当然可以 - ES2020 makes it official,而且环境多年来一直具有确定性的属性顺序

标签: javascript arrays ecmascript-6 ecmascript-5


【解决方案1】:

map 在这里使用不正确,因为您应该始终从中返回一组新结果。

您可以这样做,您可以根据需要更改顺序:

const arrOfObj = [
  {
    name: "test1",
    value: "value1"
  },
  {
    name: "test2",
    value: "value2"
  }
];

function changeKeyName(arr, oldValue, newVal) {
  return arr.map(({ [oldValue]: val, ...rest }) => {
    return {
      [newVal]: val,
      ...rest,
    };
  });
}

console.log(changeKeyName(arrOfObj, "name", "type"));

【讨论】:

  • 这不会导致被替换对象的属性顺序被维护,这是 OP 关注的主要问题 - 您在对象的开头硬编码新属性。您还需要为 newVal 使用计算属性
【解决方案2】:

您可以使用Object.entries 获取一组条目,然后映射它们,找到时用新键替换旧键:

var arrOfObj = [
  {
    name: "test1",
    value: "value1"
  },
  {
    name: "test2",
    value: "value2"
  }
];

const changeKeyName = (arr, oldKey, newKey) => arr.map(
  item => Object.fromEntries(
    Object.entries(item).map(
      ([key, val]) => [key === oldKey ? newKey : key, val]
    )
  )
);
console.log(changeKeyName(arrOfObj, "name", "type"));

(与流行的看法相反,对象属性顺序保证by the specification,并且已在所有环境中实施多年。但请记住,这仅适用于 不是数组索引 - 数组索引如 0 1 2 不能相对于其他属性进行排序,它们总是会首先迭代,按数字升序排列)

也就是说,如果代码的编写使得属性顺序无关紧要,则通常更容易理解 - 如果您的代码依赖于特定顺序的属性,我建议重构它以便属性顺序没关系。

【讨论】:

  • 除了不修改原来的item,和OPs代码相比,这并没有真正改变什么?
  • OP 的问题是他的 delete 正在从对象中的 first 属性中删除 name 属性,并将其替换为 type 属性,该属性设置为对象的 second 属性。他想要{ type: someVal, value: someVal },而不是{ value: someVal, type: someVal }
  • @epascarello 仅当 name 预先知道是对象中的第一个属性时才有效(否则,属性顺序会丢失)
  • 哎呀,我的意思是把它放在 OP 问题上,而不是你的答案上。大声笑
  • @li97 您必须使用不支持 fromEntries 的旧 IDE 或环境 - 使用 a polyfill
猜你喜欢
  • 1970-01-01
  • 2017-10-12
  • 2014-03-03
  • 1970-01-01
  • 1970-01-01
  • 2014-02-08
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
相关资源
最近更新 更多