删除嵌套数组中具有键值的对象

4

我想删除每个部分下唯一的低级对象(例如在下面的代码中,在个人数据下有两个对象…我想删除其中一个操作为OLD的对象),其中“action”:“OLD”

我在我的项目中使用lodash

[
  {
    "clientDetails": {
      "personalData": [
        {
          "action": "NEW",
          "id": "12345"
        },
        {
          "action": "OLD",
          "id": "12445"
        }
      ]
    },
    "clientAddress": {
      "primaryAddress": [
        {
          "action": "OLD",
          "id": "12345"
        },
        {
          "action": "NEW",
          "id": "12445"
        }
      ],
      "secondaryAddress": [
        {
          "action": "NEW",
          "id": "12345"
        },
        {
          "action": "OLD",
          "id": "12445"
        }
      ]
    }
  },
  {
    "clientDemise": {
      "deathDetails": [
        {
          "action": "NEW",
          "id": "12345"
        },
        {
          "action": "OLD",
          "id": "12445"
        }
      ]
    },
    "clientMarital": {
      "divorceInformation": [
        {
          "action": "OLD",
          "id": "12345"
        },
        {
          "action": "NEW",
          "id": "12445"
        }
      ],
      "marraigeInformation": [
        {
          "action": "NEW",
          "id": "12345"
        },
        {
          "action": "OLD",
          "id": "12445"
        }
      ]
    }
  }
]

非常抱歉之前的表述有误,这是我第一次发问题。


这个应该输出什么? - pritesh
7个回答

2
只需要几行代码就能实现这个功能。考虑到技术相关性,下面的内容将对此进行详细说明。
input = your input

这段代码将会完成任务。
for (var i of input) {
  for (var j in i) {
   var ob = i[j];
   for (var k in ob) {
     var index = _.findIndex(ob[k], {'action': 'OLD'});
     if (index > -1) {
       ob[k].splice(index, 1);
     }
   }
 }
}

这是一个不错的简短解决方案。你可以顺便删除 toRemove 变量。此外,你可以将其转换为代码片段,并将 lodash 作为外部库包含进去。 - Cully
非常感谢您的建议,我已经删除了不必要的变量。如果需要,我会创建代码片段。 - Shyam Tayal
你的代码可以运行...谢谢...但是它会抛出错误ob[k].splice不是一个函数。例如,在上面的代码中,如果没有主地址@ShyamTayal。 - deepak reddy yasa
我正在考虑将最后一级字段作为数组处理,如果不是,请在第三个循环中添加类型检查以避免任何错误。希望这可以帮助到您。 - Shyam Tayal
@ShyamTayal 谢谢,它起作用了,我还有一个问题,它也删除了没有操作的对象。 - deepak reddy yasa
显示剩余2条评论

1
你可以使用JavaScript过滤器。不使用lodash可以减小捆绑包大小。
// it's upto you, you can use new Array() as well and insert if(ktm.action==='NEW')
clients = clients.filter(function(itm) {
  Object.keys(itm).forEach(function(Okey, Ovalue) {
    Object.keys(itm[Okey]).forEach(function(inkey, invalue) {
      itm[Okey][inkey].filter(function(ktm) {
        if (ktm.action === 'OLD') {
          // perform your logic, either you can insert into new Array() or 
          // delete that object and return clients
        }
      });
    });
  });
});

1

让我们不要改变原始输入数据,使用自定义程序进行克隆,并在自定义程序中拒绝不需要的内容(如果存在),以获得预期的更干净的克隆输出。您可以使用lodash#cloneDeepWith

_.cloneDeepWith(input, v => _.find(v, {action: "OLD"}) ? _.reject(v, {action: "OLD"}) : undefined);

这只是一个例子,展示了你想要拒绝的内容(硬编码)。但你可以将其包装在回调函数中,并将拒绝标准作为参数传递以使其动态化。

所以我们开始吧:

let input = [{"clientDetails":{"personalData":[{"action":"NEW","id":"12345"},{"action":"OLD","id":"12445"}]},"clientAddress":{"primaryAddress":[{"action":"OLD","id":"12345"},{"action":"NEW","id":"12445"}],"secondaryAddress":[{"action":"NEW","id":"12345"},{"action":"OLD","id":"12445"}]}},{"clientDemise":{"deathDetails":[{"action":"NEW","id":"12345"},{"action":"OLD","id":"12445"}]},"clientMarital":{"divorceInformation":[{"action":"OLD","id":"12345"},{"action":"NEW","id":"12445"}],"marraigeInformation":[{"action":"NEW","id":"12345"},{"action":"OLD","id":"12445"}]}}],
    clear = (input, rej) => (
      _.cloneDeepWith(input, v => _.find(v, rej) ? _.reject(v, rej) : undefined)
    ),
    res;
  
res = clear(input, {action: "OLD"}); //you can filter out action: OLD
console.log(res);

res = clear(input, {action: "NEW"}); //you can filter out action: NEW
console.log(res);

res = clear(input, d => d.action==="OLD"); //you can filter with custom callback with complex logic
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>


谢谢了,很棒的lodash库,你救了我的命。 - Fernando Cesar

1

你可以通过以下方式实现此操作,无需使用lodash:

var data = [{ "clientDetails": { "personalData": [{ "action": "NEW", "id": "12345" }, { "action": "OLD", "id": "12445" } ] }, "clientAddress": { "primaryAddress": [{ "action": "OLD", "id": "12345" }, { "action": "NEW", "id": "12445" } ], "secondaryAddress": [{ "action": "NEW", "id": "12345" }, { "action": "OLD", "id": "12445" } ] } }, { "clientDemise": { "deathDetails": [{ "action": "NEW", "id": "12345" }, { "action": "OLD", "id": "12445" } ] }, "clientMarital": { "divorceInformation": [{ "action": "OLD", "id": "12345" }, { "action": "NEW", "id": "12445" } ], "marraigeInformation": [{ "action": "NEW", "id": "12345" }, { "action": "OLD", "id": "12445" } ] } } ]

const removeOld = (data) => data.map(x => 
   Object.entries(x).reduce((r, [k,v]) => {
      r[k] = Object.entries(v).map(([o,p]) => 
        ({[o]: p.filter(n => n.action != 'OLD')}))
      return r
   },{}))

console.log(removeOld(data))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

使用mapObject.entriesreducefilter
另一种方法是利用递归,类似于@Vanojx1的方法,但在ES6中:

var data = [{ "clientDetails": { "personalData": [{ "action": "NEW", "id": "12345" }, { "action": "OLD", "id": "12445" } ] }, "clientAddress": { "primaryAddress": [{ "action": "OLD", "id": "12345" }, { "action": "NEW", "id": "12445" } ], "secondaryAddress": [{ "action": "NEW", "id": "12345" }, { "action": "OLD", "id": "12445" } ] } }, { "clientDemise": { "deathDetails": [{ "action": "NEW", "id": "12345" }, { "action": "OLD", "id": "12445" } ] }, "clientMarital": { "divorceInformation": [{ "action": "OLD", "id": "12345" }, { "action": "NEW", "id": "12445" } ], "marraigeInformation": [{ "action": "NEW", "id": "12345" }, { "action": "OLD", "id": "12445" } ] } } ]

const removeOld = (data) => 
  Array.isArray(data) ? data.filter(x => x.action != 'OLD').map(x => removeOld(x)) :
  typeof(data) == 'object' ? Object.entries(data).reduce((r, [k,v]) => (r[k] = removeOld(v), r), {}) : 
  data

console.log(removeOld(data))


0

你可以这样进行深拷贝:

    const array = [
      {
        "clientDetails": {
          "personalData": [
            {
              "action": "NEW",
              "id": "12345"
            },
            {
              "action": "OLD",
              "id": "12445"
            }
          ]
        },
        "clientAddress": {
          "primaryAddress": [
            {
              "action": "OLD",
              "id": "12345"
            },
            {
              "action": "NEW",
              "id": "12445"
            }
          ],
          "secondaryAddress": [
            {
              "action": "NEW",
              "id": "12345"
            },
            {
              "action": "OLD",
              "id": "12445"
            }
          ]
        }
      },
      {
        "clientDemise": {
          "deathDetails": [
            {
              "action": "NEW",
              "id": "12345"
            },
            {
              "action": "OLD",
              "id": "12445"
            }
          ]
        },
        "clientMarital": {
          "divorceInformation": [
            {
              "action": "OLD",
              "id": "12345"
            },
            {
              "action": "NEW",
              "id": "12445"
            }
          ],
          "marraigeInformation": [
            {
              "action": "NEW",
              "id": "12345"
            },
            {
              "action": "OLD",
              "id": "12445"
            }
          ]
        }
      }
    ]    
    function removeOldAction(a) {
    if (a instanceof Array) {
        let copiee = [];
        for (let item in a) {
            const propValue = removeOldAction(a[item]);
            if(propValue) {
                copiee.push(propValue);
            }
        }
        return copiee;
    }
    if (a instanceof Object) {
        if (a['action'] === 'OLD') { 
            return; 
        }
        let copiee = {};
        for (let key in a) {
            copiee[key] = removeOldAction(a[key]);
        }
        return copiee;
    } 
    return a;
}

    console.log(removeOldAction(array));

0

如果你的数据结构会比较一致(例如像你在问题中提到的那样),你可以尝试这样做:

const mapObj = (f, obj) => {
    return Object.keys(obj).reduce((acc, key) => {
        acc[key] = f(obj[key], key)
        return acc
    }, {})
}

const filterData = data => {
    // the data itself is an array, so iterate over each item in the array
    return data.map(x1 => {
        // x1 is an object, so need to iterate over each item in the object
        return mapObj(x2 => {
            // x2 is an object, so need to iterate over each item in the object
            return mapObj(x3 => {
                // x3 is an array of objects. each item in the array has an action key which could equal "NEW" or "OLD". get rido of the items with action === "OLD"
                return x3.filter(x4 => x4.action !== "OLD")
            }, x2)
        }, x1)
    })
}

const data = [
  {
    "clientDetails": {
      "personalData": [
        {
          "action": "NEW",
          "id": "12345"
        },
        {
          "action": "OLD",
          "id": "12445"
        }
      ]
    },
    "clientAddress": {
      "primaryAddress": [
        {
          "action": "OLD",
          "id": "12345"
        },
        {
          "action": "NEW",
          "id": "12445"
        }
      ],
      "secondaryAddress": [
        {
          "action": "NEW",
          "id": "12345"
        },
        {
          "action": "OLD",
          "id": "12445"
        }
      ]
    }
  },
  {
    "clientDemise": {
      "deathDetails": [
        {
          "action": "NEW",
          "id": "12345"
        },
        {
          "action": "OLD",
          "id": "12445"
        }
      ]
    },
    "clientMarital": {
      "divorceInformation": [
        {
          "action": "OLD",
          "id": "12345"
        },
        {
          "action": "NEW",
          "id": "12445"
        }
      ],
      "marraigeInformation": [
        {
          "action": "NEW",
          "id": "12345"
        },
        {
          "action": "OLD",
          "id": "12445"
        }
      ]
    }
  }
]

const result = filterData(data)
console.log(result)

如果您想要一个更通用的解决方案,可以处理任何结构的数据,并仅删除所有操作等于“OLD”的对象:

const reduceObj = (f, initial, obj) => {
    return Object.keys(obj).reduce((acc, key) => {
        return f(acc, obj[key], key)
    }, initial)
}

const isObject = x => x !== null && typeof x === 'object'

const removeAllOld = data => {
    if(Array.isArray(data)) {
        return data.reduce((acc, value) => {
            // don't include the item if it has a key named 'action' that is equal to 'OLD'
            if(value.action && value.action === 'OLD') return acc

            acc.push(removeAllOld(value))
            return acc
        }, [])
    }
    else if(isObject(data)) {
        return reduceObj((acc, value, key) => {
            // don't include the item if it has a key named 'action' that is equal to 'OLD'
            if(value.action && value.action === 'OLD') return acc

            acc[key] = removeAllOld(value)
            return acc
        }, {}, data)
    }
    else {
        return data
    }
}

const data = [
  {
    "clientDetails": {
      "personalData": [
        {
          "action": "NEW",
          "id": "12345"
        },
        {
          "action": "OLD",
          "id": "12445"
        }
      ]
    },
    "clientAddress": {
      "primaryAddress": [
        {
          "action": "OLD",
          "id": "12345"
        },
        {
          "action": "NEW",
          "id": "12445"
        }
      ],
      "secondaryAddress": [
        {
          "action": "NEW",
          "id": "12345"
        },
        {
          "action": "OLD",
          "id": "12445"
        }
      ]
    }
  },
  {
    "clientDemise": {
      "deathDetails": [
        {
          "action": "NEW",
          "id": "12345"
        },
        {
          "action": "OLD",
          "id": "12445"
        }
      ]
    },
    "clientMarital": {
      "divorceInformation": [
        {
          "action": "OLD",
          "id": "12345"
        },
        {
          "action": "NEW",
          "id": "12445"
        }
      ],
      "marraigeInformation": [
        {
          "action": "NEW",
          "id": "12345"
        },
        {
          "action": "OLD",
          "id": "12445"
        }
      ]
    }
  }
]

console.log(removeAllOld(data))


0

在每个对象节点中进行结构无关的解决方案检查

var data=[{clientDetails:{personalData:[{action:"NEW",id:"12345"},{action:"OLD",id:"12445"}]},clientAddress:{primaryAddress:[{action:"OLD",id:"12345"},{action:"NEW",id:"12445"}],secondaryAddress:[{action:"NEW",id:"12345"},{action:"OLD",id:"12445"}]}},{clientDemise:{deathDetails:[{action:"NEW",id:"12345"},{action:"OLD",id:"12445"}]},clientMarital:{divorceInformation:[{action:"OLD",id:"12345"},{action:"NEW",id:"12445"}],marraigeInformation:[{action:"NEW",id:"12345"},{action:"OLD",id:"12445"}]}}];

const reducer = (curr) => {
  if(_.isArray(curr))
    return _(curr)
      .filter(el => !('action' in el && el.action == 'OLD'))
      .map(el => reducer(el))
      .value()
  else if(_.isObject(curr)) {
    return _(curr)
      .mapValues(el => reducer(el))
      .value()
  } else
    return curr;
};

console.log(reducer(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接