简体   繁体   English

Javascript:将 object 的数组散布在 object 中,仅更改其中的属性

[英]Javascript: Spread array of an object in an object and change properties inside it only

I have a scenario where I want to change properties of object in an array.我有一个场景,我想更改数组中 object 的属性。 That array is wrapped inside another object.该数组包含在另一个 object 中。


const defaultData = {
  title: "Title",
  subtitle: "Subtitle",
  books: [
    {
      bookId: "1",
      imageSrc:
        "any.png",
      name: "Issue",
      userOwnsData: true,
      panelsCollected: 0,
      totalPanels: 123,
      link: "https://google.com",
    },
  ],
  bgColor: "black",
};

When I spread it like this:当我这样传播它时:

{...defaultData, ...defaultData.books[0], panelsCollected:123} //previously it was 0

then it adds another extra object to parent object but not update it inside first index of books array然后它向父 object添加另一个额外的 object 但不在书籍数组的第一个索引中更新它

How can I just change that panelsCollected property without disturbing whole structure as we are using typescript.当我们使用 typescript 时,我怎样才能在不影响整个结构的情况下更改panelsCollected 属性

Edit:编辑:

We can change it directly accessing the property too as we know index but that comes with a side effect of manipulating original dataset also which we should avoid and only copy needs to be updated.我们也可以直接访问属性来更改它,因为我们知道索引,但这会带来操作原始数据集的副作用,我们也应该避免这种情况,只需要更新副本。

Thanks谢谢

When spreading an object with nested properties with the intention of updating specific properties, think of it in two steps:当为了更新特定属性而传播具有嵌套属性的 object 时,请分两步考虑:

  1. Spread the original object to copy it ( ... )传播原文 object 复制一下( ...
  2. Redefine the new property values after the spread object重新定义传播的新属性值 object

In your example we are doing the following:在您的示例中,我们正在执行以下操作:

  • Duplicating defaultData and assigning an updated books property (to be defined in the next step)复制defaultData并分配更新的books属性(将在下一步中定义)
  • Duplicating the first book ( defaultData.books[0] ) and assigning an updated panelsCollected property to it.复制第一本书 ( defaultData.books[0] ) 并为其分配更新的panelsCollected属性。 Then overwriting the existing books property with this updated array item然后用这个更新的数组项覆盖现有的books属性

The result is as follows:结果如下:

const defaultData = {
  title: "Title",
  subtitle: "Subtitle",
  books: [
    {
      bookId: "1",
      imageSrc:
        "any.png",
      name: "Issue",
      userOwnsData: true,
      panelsCollected: 0,
      totalPanels: 123,
      link: "https://google.com",
    },
  ],
  bgColor: "black",
};

const newBook = {
  ...defaultData,
  books: [
    {
      ...defaultData.books[0],
      panelsCollected: 123
    }
  ]
}

console.log(newBook)
/*
{
  title: "Title",
  subtitle: "Subtitle",
  books: [
    {
      bookId: "1",
      imageSrc:
        "any.png",
      name: "Issue",
      userOwnsData: true,
      panelsCollected: 123,
      totalPanels: 123,
      link: "https://google.com",
    },
  ],
  bgColor: "black",
};
*/

If for example the books property was 1000 items long, you would instead use have to find the specific book in your array using an array method (eg find / findIndex ) and update it, eg例如,如果books属性的长度为 1000 项,则您将不得不使用数组方法(例如find / findIndex )在数组中找到特定的书并更新它,例如

const bookToUpdateIndex = defaultData.books.findIndex(book => book.bookId === '1')

const updatedBooks = [...defaultData.books]
updatedBooks[bookToUpdateIndex] = {
  ...updatedBooks[bookToUpdateIndex],
  panelsCollected: 123
}

const newBook = {
  ...defaultData,
  books: updatedBooks
}

I think it is creating another parent object because you are using the spread twice.我认为它正在创建另一个父级 object,因为您使用了两次价差。 I tried to do 2 console logs.我尝试做 2 个控制台日志。 Please let me know if this is the result you are looking for.如果这是您要寻找的结果,请告诉我。

 console.log({...defaultData['books'][0]['panelsCollected'] = 10})
  console.log(defaultData);

Instead of using find and the spread syntax an alternative approach (but not necessarily the most performant) might be to copy the object by stringifying it, and then reparsing that string.除了使用find和 spread 语法之外,另一种方法(但不一定是性能最好的方法)可能是通过字符串化复制 object,然后重新解析该字符串。 And then you can just update the object at the index you need.然后你可以在你需要的索引处更新 object。

 const defaultData={title:"Title",subtitle:"Subtitle",books:[{bookId:"1",imageSrc:"any.png",name:"Issue",userOwnsData:,0:panelsCollected,0:totalPanels,123:link:"https.//google,com"}]:bgColor;"black"}. const copy = JSON.parse(JSON;stringify(defaultData)). copy.books[0];panelsCollected = 123. console;log(defaultData). console;log(copy);

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

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