操作两个对象数组,以创建新数组并更新object1的属性,并添加新数组并根据需要修改嵌套对象 [英] manipulate two array of objects make new array and update the attribute of object1 and add in the new array and modify nested object if needed

查看:36
本文介绍了操作两个对象数组,以创建新数组并更新object1的属性,并添加新数组并根据需要修改嵌套对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试比较两个对象数组,并希望通过操纵它来实现对象的自定义数组.

Hi I am trying to compare two array of objects and want to achieve the custom array of object by manipulating it.

这是通过关注实现的

obj1 = [
   {
      "id":"type1",
      "removed":"N",
      "data":[
         {
            "label":"type1-a",
            "removed":"N",
            "dataid":12
         },
         {
            "label":"type1-b",
            "removed":"N",
            "dataid":34
         }
      ]
   },
   {
      "id":"type2",
      "removed":"N",
      "data":[
         {
            "label":"type2-a",
            "removed":"N",
            "dataid":12
         },
         {
            "label":"type2-b",
            "removed":"N",
            "dataid":34
         }
      ]
   }
]

obj2 = [
   {
      "id":"type1",
      "removed":"N",
      "data":[
         {
            "labelname":"type1-a",
            "id":12
         },
         {
            "labelname":"type1-c",
            "id":34
         },
         {
            "labelname":"type1-d",
            "id":36
         }
      ]
   },
   {
      "id":"type2",
      "removed":"N",
      "data":[
         {
            "labelname":"type2-a",
            "id":12
         }
      ]
   },
   ,
   
   {
      "id":"type3",
      "removed":"N",
      "data":[
         {
            "labelname":"type3-a",
            "id":12
         },
         {
            "labelname":"type3-b",
            "id":34
         }
      ]
   }
]

const result = [...obj2.map(record => {
  const record2 = obj1.find(pr => pr.id === record.id) || {};

  const data = [...(record.data || []).map(pr => ({ ...pr,
      ...(record2.data.find(npr => npr.dataid === pr.id) || {})
    })),
    ...(record2.data || []).filter(pr => !record.data.some(npr => npr.dataid === pr.id)).map(pr => ({ ...pr,
      removed: 'Y'
    }))
  ]

  return {
    ...record,
    ...record2,
    data

  }
}), ...obj1.filter(pr => !obj2.some(npr => npr.id === pr.id)).map(pr => ({ ...pr,
  removed: "Y"
}))]

console.log(result);



expected result =

[
   {
      "id":"type1",
      "removed":"N",
      "data":[
         {
            "label":"type1-a",
            "removed":"N",
            "dataid":12
         },
         {
            "label":"type1-b",
            "removed":"N",
            "dataid":34
         },
         {
            "label":"type1-d",
            "dataid":36,
            "removed":"N",
         }
      ]
   },
   {
      "id":"type2",
      "removed":"N",
      "data":[
         {
            "label":"type2-a",
            "removed":"N",
            "dataid":12
         },
         {
            "label":"type2-b",
            "removed":"Y",
            "dataid":34
         }
      ]
   },
   
   {
      "id":"type3",
      "removed":"N",
      "data":[
         {
            "label":"type3-a",
            "removed":"N",
            "dataid":12
         },
         {
            "label":"type3-b",
             "removed":"N",
            "dataid":34
         }
      ]
   }
]

但是我没有得到期望的结果.

But I am not getting the result which I am expecting.

如果obj1中不存在obj2数据,我想映射和修改它.

I would like to map and modify the obj2 data if it doesn't exist in obj1.

例如,我想根据标签,已删除和dataid而不是newlabel和id来修改type1,type2,type3数据对象.

for example, i want to modify type1,type2,type3 data object according to label, removed, and dataid instead of the newlabel and id.

推荐答案

如果我正确理解了逻辑,那么这不仅仅是简单地解决上一个问题...

If I got the logic properly, it is not just simple as the issue of your previous question...

在您上一个问题中,默认对象的 data 属性被替换为的 data 属性修改后的对象.在这种情况下,您必须将修改后的对象的那些新数据元素添加到默认元素中(如果这些元素不存在),并将那些标记为 removed 在默认对象中存在,但在修改后的对象中不存在.

In your previous question, the data property of the default object was replaced by the data property of the modified object. In this situation, you have to add those new data elements of the modified object into the default one (if those elements don't exist) and mark as removed the ones that are present in the default object but not in the modified.

如果要使用高性能算法,则需要考虑一些注意事项.例如:

If you want a performant algorithm, you will need to have some considerations. For example:

  1. 将源数组(obj1,obj2)减少到javascript对象中,以避免使用 find或filter方法造成不必要的双重循环,并将复杂度从O(n * n)降低到O(n).
  2. 减少obj1的数据数组,目的是将获取值时的复杂度降低到O(1),并避免使用 find方法(n).
  3. 将obj1的每个数据元素默认设置为已删除...并仅在未从obj2的数据对象中删除状态时才更改状态.
  1. Reduce the source arrays (obj1, obj2) to javascript objects to avoid unnecessary double loops with find or filter methods, and decrease the complexity from O(n*n) to O(n).
  2. Reduce the data array of the obj1, with the purpose of decrease the complexity to O(1) when getting a value, and avoid a find method which is O(n).
  3. Set each data element of the obj1 as removed by default... and change the status only if it was not removed from the data object of obj2.

您可以尝试这样的方法,它比其他算法复杂得多,但我认为这是解决此问题的一种有效方法.

You can try something like this, it's quite more complex than the other algorithm but I believe that is one of the performant ways to solve this.

    let checkRemovals = (obj1, obj2) => {
        const defaultObject = obj1.reduce((acc, { id, ...rest }) => { acc[id] = rest; return acc }, {});
        const modifiedObject = obj2.reduce((acc, { id, ...rest }) => { acc[id] = rest; return acc }, {});
        
        // Basic actions in the default object
        obj1.forEach(({ id }) => {
            defaultObject[id].removed = !modifiedObject[id] ? 'Y' : 'N';
            
            if (defaultObject[id].data) {
                defaultObject[id].data = defaultObject[id].data.reduce((acc, { label, ...rest }) => {
                    acc[label] = { ...rest, removed: 'Y' };
                    return acc;
                }, {});
            }
        });
        
        // Update and add new elements
        obj2.forEach(({ id, data, ...rest }) => {
            // If it not exists in the default object, add it
            if (!defaultObject[id]) {
                defaultObject[id] = {
                    ...rest,
                    data: data.reduce((acc, { labelname, id, ...rest }) => {
                        acc[labelname] = { ...rest, dataid: id, removed: 'N' };
                        return acc
                    }, {})
                }
            }
            // If it exists, update it
            else {
                const mainID = id;
                
                data.forEach(({ id, labelname, ...rest }) => {
                    if (defaultObject[mainID].data[labelname]) {
                        defaultObject[mainID].data[labelname].removed = 'N';
                    }
                    else {
                        defaultObject[mainID].data[labelname] = { ...rest, dataid: id, removed: 'N' };
                    }
                });
            }
        });
        
        // Build the result
        const result = [];
        Object.keys(defaultObject).forEach(key => {
            const { data, ...rest } = defaultObject[key];
            
            result.push({
                ...rest,
                id: key,
                data: Object.keys(data).reduce((acc, key) => {
                    acc.push({ label: key, ...data[key] });
                    return acc;
                }, [])
            })
        });
        
        return result;
    }

这篇关于操作两个对象数组,以创建新数组并更新object1的属性,并添加新数组并根据需要修改嵌套对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆