【问题标题】:How to change an object Key without mutating original array如何在不改变原始数组的情况下更改对象键
【发布时间】:2019-10-26 09:31:20
【问题描述】:

我有一个对象数组 - 我想在不改变原始数组的情况下将其中一个对象键更改为其他值。解决这个问题的最佳方法是什么?

我知道我可以使用 Map 方法,但不确定它是如何工作的。谢谢

const books = [
  { title: "To Kill a Mockingbird", writtenBy: "Harper Lee" }, 
  { title: "A Clockwork Orange",  author: "Anthony Burgess" },
  { title: "The Elephant Tree", writtenBy: "R.D. Ronald" } 
]

function changeKey(arr, keyChange, newKey) {

}

// i want to return so the KEY keyChange(author) is changed to newKey(writtenBy)
[
 { title: "To Kill a Mockingbird", writtenBy: "Harper Lee" },
 { title: "A Clockwork Orange",  writtenBy: "Anthony Burgess" },
 { title: "The Elephant Tree", writtenBy: "R.D. Ronald" } 
]

【问题讨论】:

  • 不确定我是否理解这个问题:books 是一个 const 数组与这个问题 100% 无关,因为您想更改其中一个包含对象中的字段,所以......只需更改它? let e = books.find(......); e.writtenBy = e.author; delete e.author; 完成了吗? (使用Array.find() 函数,如果您需要在每个元素上运行它,forEach 应该可以避免使用find()

标签: javascript arrays javascript-objects


【解决方案1】:

以下内容不会改变 books 数组。

const books = [
  { title: "To Kill a Mockingbird", writtenBy: "Harper Lee" },
  { title: "A Clockwork Orange", author: "Anthony Burgess" },
  { title: "The Elephant Tree", writtenBy: "R.D. Ronald" }
];

const renamedBooks = books.map(book => {
  if (book.author) {
    return {
      title: book.title,
      writtenBy: book.author
    };
  }

  return book;
});

console.info(renamedBooks);

【讨论】:

  • 这有点奇怪,因为它不会创建没有作者密钥的对象的副本。它们在changeKey中没有改变,所以它确实正确地回答了这个问题,但是如果它们在它们仍然是同一个对象之后被改变了。例如。 delete renamedBooks[0].title; console.log( books[0] );
  • 我们不一定需要创建副本,不是吗?以上回答了问题How to change an objectKey without mutating original array
  • 是的,我说它正确回答了这个问题。在我看来,由于我所说的原因,它只是不能很好地回答它。如果 OP 使用它,他可能会对它感到满意,认为它创建了每个对象的副本,然后他们可能会修改 renamedBooks 中的对象,而不期望它会影响 books 中的对象,并导致错误。
  • OP 询问的function changeKey(arr, keyChange, newKey) 在哪里?
  • OP 要求在哪里必须包含changeKey()? IIUC,这就是 OP 要求的 I have an array of objects - I want to change one of the object keys to something else without mutating the original array. what is the best method to approach this?
【解决方案2】:

您可以map 参数数组并使用展开运算符浅层复制其中的每个对象。对于每个新对象,如果它包含我们要删除的键,请将值复制到新键和 delete 旧键。

const books = [ {title: "To Kill a Mockingbird", writtenBy: "Harper Lee"}, {title: "A Clockwork Orange", author: "Anthony Burgess"}, {title: "The Elephant Tree", writtenBy: "R.D. Ronald"} ];

const changeKey = (arr, keyChange, newKey) =>
  arr.map(e => {
    const o = {...e};
    
    if (keyChange in o) {
      o[newKey] = o[keyChange];
      delete o[keyChange];
    }
    
    return o;
  })
;

console.log(changeKey(books, "author", "writtenBy"));
console.log(books);

【讨论】:

    【解决方案3】:

    map、filter、reduce 等数组助手不会改变原始数组,它们会返回一个新数组。 Map 接收一个函数作为参数(回调)。 Map 迭代数组,在每个元素中应用你的回调。

    const books = [ {title: "To Kill a Mockingbird", writtenBy: "Harper Lee"},
                    {title: "A Clockwork Orange",  author: "Anthony Burgess"},
                    {title: "The Elephant Tree", writtenBy: "R.D. Ronald"} ];
    
    //Function to use as a callback on map
    function changeKey(current) {
      if(current.author) return { title: current.title, writtenBy: current.author };
      return current;
    }
    
    //Creating new array applying changeKey in every element thanks to map
    const newBooks = books.map(changeKey);
    console.log(newBooks);

    【讨论】:

    • 这有点奇怪,因为它不会创建没有作者密钥的对象的副本。它们在changeKey中没有改变,所以它确实正确地回答了这个问题,但是如果它们在它们仍然是同一个对象之后被改变了。例如。 delete newBooks[0].title; console.log( books[0] );
    猜你喜欢
    • 2019-10-03
    • 1970-01-01
    • 2018-01-12
    • 2021-06-09
    • 2012-03-24
    • 2021-12-02
    • 2022-11-12
    • 1970-01-01
    • 2021-04-14
    相关资源
    最近更新 更多