如何更改嵌套对象阵列的使用情况

发布于 2025-02-14 01:59:35 字数 1197 浏览 0 评论 0原文

我有一个状态:

const obj = [{id: "1", obj_of_names: [{
                             id: "a1",
                             name: "abc",
                             school: "xyz" },
                            { id:"b1",
                             name: "def",
                             school: "zyx" },
                            { id:"c1",
                             name: "ghi",
                             school: "pqr" }]
             },
             {id: "2", obj_of_names: [{
                             id: "d1",
                             name: "abc123",
                             school: "xyz123" }]
             }]

const [newobj, setObj] = useState("obj")

现在我想更新ID:D1内部ID:2的学校。假设旧价值是学校:xyz123现在我想将其更新到学校:newxyz123。 如何使用传播操作员或其他方法来实现这一目标?

我尝试了以下代码:

setObj((prevObjects) => {
            const tempIndex = prevObjects.findIndex(
                (item) => item.id === reqdImgID
            );
const newObject = obj[tempIndex].obj_of_names.map((obj) => { 
if (obj.id == reqdID) { 
return {  ...obj, 
school: newSchool,};}
return obj; }););

但是我将其作为OUPUT: { id:“ C1”, 名称:“ Ghi”, 学校:“ newxyz123” }

I have a state:

const obj = [{id: "1", obj_of_names: [{
                             id: "a1",
                             name: "abc",
                             school: "xyz" },
                            { id:"b1",
                             name: "def",
                             school: "zyx" },
                            { id:"c1",
                             name: "ghi",
                             school: "pqr" }]
             },
             {id: "2", obj_of_names: [{
                             id: "d1",
                             name: "abc123",
                             school: "xyz123" }]
             }]

const [newobj, setObj] = useState("obj")

Now I want to update school for the id:d1 inside id:2. Suppose the old value is school: xyz123 now I want to update it to school: newxyz123.
How can I achieve this using the spread operator or by another method?

I tried the below code:

setObj((prevObjects) => {
            const tempIndex = prevObjects.findIndex(
                (item) => item.id === reqdImgID
            );
const newObject = obj[tempIndex].obj_of_names.map((obj) => { 
if (obj.id == reqdID) { 
return {  ...obj, 
school: newSchool,};}
return obj; }););

But I am getting this as an ouput:
{
id:"c1",
name: "ghi",
school: "newxyz123"
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不知所踪 2025-02-21 01:59:35

我建议创建一个接收原始数组,匹配器函数和替换功能的函数。此功能的目的是返回具有更改值的新数组。

function mutateObject(array, matcher, replacer) {
    // returns a new array, with all elements untouched, except for those that match the matcher function, which are replaced with new objects created by the replacer function
    return array.map(function (item) {
        return matcher(item) ? {...replacer(item)} : item;
    });
}

然后,使用该函数替换值。

mutateObject(obj, group => group.id == "2", group => {
    const newNames = mutateObject(group.obj_of_names, name => name.id === "d1", name => ({ ...name, school: "newxyz123" }));
    return { ...group, obj_of_names: newNames }
});

这将做什么:

  1. 使用原始数组,找到ID(根对象中)为“ 2”的对象。
  2. 应用替代功能,该功能将:
    1. 使用obj_of_names查找ID为“ D1”的对象。
    2. 使用传播操作员,应用替换函数以返回带有新的学校价值的新对象。
    3. 返回一个由替换obj_of_names对象克隆的新对象,其中包含替换的学校价值。

当然,您可以通过使用各种库克隆对象,突变并返回新对象来提高此代码及其可读性,但是如果您想开始使用,则可以解决。
另外,如果您想更改学校名称,建议使用@aweimon引用的答案,但是如果您想在各种标准上更改多个对象,则可以改善上述功能。

const obj = [{
    id: "1",
    obj_of_names: [{
        id: "a1",
        name: "abc",
        school: "xyz"
      },
      {
        id: "b1",
        name: "def",
        school: "zyx"
      },
      {
        id: "c1",
        name: "ghi",
        school: "pqr"
      }
    ]
  },
  {
    id: "2",
    obj_of_names: [{
      id: "d1",
      name: "abc123",
      school: "xyz123"
    }]
  }
]

function mutateObject(array, matcher, replacer) {
  // returns a new array, with all elements untouched, except for those that match the matcher function, which are replaced with new objects created by the replacer function
  return array.map(function(item) {
    return matcher(item) ? { ...replacer(item)
    } : item;
  });
}

const updatedObj = mutateObject(obj, group => group.id == "2", group => {
  const newNames = mutateObject(group.obj_of_names, name => name.id === "d1", name => ({ ...name,
    school: "newxyz123"
  }));
  return { ...group,
    obj_of_names: newNames
  }
});

console.log(updatedObj);

I suggest creating a function that receives the original array, a matcher function, and a replace function. The purpose of this function is to return a new array with the value changed.

function mutateObject(array, matcher, replacer) {
    // returns a new array, with all elements untouched, except for those that match the matcher function, which are replaced with new objects created by the replacer function
    return array.map(function (item) {
        return matcher(item) ? {...replacer(item)} : item;
    });
}

Then, use the function to replace the values.

mutateObject(obj, group => group.id == "2", group => {
    const newNames = mutateObject(group.obj_of_names, name => name.id === "d1", name => ({ ...name, school: "newxyz123" }));
    return { ...group, obj_of_names: newNames }
});

What this will do:

  1. Using the original array, find the object where the id (in the root object) is "2".
  2. Apply the replacer function, which will:
    1. Use the obj_of_names to find the object where the id is "d1".
    2. Apply the replacer function to return a new object with the new school value, using the spread operator.
    3. Return a new object cloned by the spread operator with replaced obj_of_names object, which contains the replaced school value.

Of course, you can improve this code and its readability by using various libraries to clone the objects, mutate them, and return new objects, but it is a workaround if you want to get started.
Also, if you want to change the school name, I suggest using the answer @aweimon referenced, but if you want to change multiple objects on various criteria, you can improve the function above.

const obj = [{
    id: "1",
    obj_of_names: [{
        id: "a1",
        name: "abc",
        school: "xyz"
      },
      {
        id: "b1",
        name: "def",
        school: "zyx"
      },
      {
        id: "c1",
        name: "ghi",
        school: "pqr"
      }
    ]
  },
  {
    id: "2",
    obj_of_names: [{
      id: "d1",
      name: "abc123",
      school: "xyz123"
    }]
  }
]

function mutateObject(array, matcher, replacer) {
  // returns a new array, with all elements untouched, except for those that match the matcher function, which are replaced with new objects created by the replacer function
  return array.map(function(item) {
    return matcher(item) ? { ...replacer(item)
    } : item;
  });
}

const updatedObj = mutateObject(obj, group => group.id == "2", group => {
  const newNames = mutateObject(group.obj_of_names, name => name.id === "d1", name => ({ ...name,
    school: "newxyz123"
  }));
  return { ...group,
    obj_of_names: newNames
  }
});

console.log(updatedObj);

久夏青 2025-02-21 01:59:35
const arr = [{id: "1", obj_of_names: [{
                             id: "a1",
                             name: "abc",
                             school: "xyz" },
                            { id:"b1",
                             name: "def",
                             school: "zyx" },
                            { id:"c1",
                             name: "ghi",
                             school: "pqr" }]
             },
             {id: "2", obj_of_names: [{
                             id: "d1",
                             name: "abc123",
                             school: "xyz123" }]
             }]

您可以在另一个映射中调用映射,然后更改阵列whitin whitin the对象:

const newArr =  arr.map((item)=>{
        if(item.id == 2){
            return {...item, obj_of_names: item.obj_of_names.map((item2)=>{
    
                if(item2.id === 'd1'){
                    return {...item2, school: 'newxyz123'}
                }
    
                return item2
            }) }
        }
    
        return item
    })

    const [state, setState] = useState(arr)

然后您可以调用setState并使用newarr更新它。

const arr = [{id: "1", obj_of_names: [{
                             id: "a1",
                             name: "abc",
                             school: "xyz" },
                            { id:"b1",
                             name: "def",
                             school: "zyx" },
                            { id:"c1",
                             name: "ghi",
                             school: "pqr" }]
             },
             {id: "2", obj_of_names: [{
                             id: "d1",
                             name: "abc123",
                             school: "xyz123" }]
             }]

You can call a map inside another map and change the array whitin the object like so:

const newArr =  arr.map((item)=>{
        if(item.id == 2){
            return {...item, obj_of_names: item.obj_of_names.map((item2)=>{
    
                if(item2.id === 'd1'){
                    return {...item2, school: 'newxyz123'}
                }
    
                return item2
            }) }
        }
    
        return item
    })

    const [state, setState] = useState(arr)

Then you can call setState and update it with the newArr

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文