简体   繁体   English

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

[英]delete an object in a nested array which has key value

i want to delete the only low-level object(for example in below code, under personal data there are two objects... i want to delete one object where action: old) under each section, where "action": "OLD" 我想删除唯一的低级对象(例如在下面的代码中,在个人数据下有两个对象...我想删除一个对象,其中action:old)在每个部分下,其中“action”:“OLD”

I'm using lodash in my project 我在我的项目中使用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"
        }
      ]
    }
  }
]

sorry for the wrong presentation, this is the first time I'm posting a question 抱歉错误的演示文稿,这是我第一次发帖提问

Just few lines can achieve this considering 只需几行即可实现这一目标

input = your input

This peace of code will do the work 这种代码的和平将完成工作

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);
     }
   }
 }
}

You can use JavaScript filters. 您可以使用JavaScript过滤器。 Reduce your bundle size by not using lodash. 不使用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
        }
      });
    });
  });
});

You can achieve this via something like this without lodash: 你可以通过这样的东西实现这一点,而不需要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> 

Using map , Object.entries , reduce and filter . 使用mapObject.entriesreducefilter

Another way would be to utilize recursion similar to @Vanojx1 approach but in ES6: 另一种方法是使用类似于@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)) 

If the structure of your data is going to be fairly consistent (ie similar to what you've included in your question), you could do something like this: 如果您的数据结构相当一致(即类似于您在问题中包含的内容),您可以执行以下操作:

 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) 

If you want a more generic solution that can take data of any structure and just removes all objects with an action equal to 'OLD': 如果您想要一个更通用的解决方案,可以获取任何结构的数据,只需删除所有对象的行为等于'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)) 

you can do a deep copy like this: 你可以做这样的深层复制:

    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));

Structure independent solution checking for action in each object node 结构独立的解决方案检查每个对象节点中的操作

 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> 

Let's not mutate the original input data, clone it with a customizer, and reject the unwanted stuffs (if they exists) inside the customizer to have cleaner cloned output as expected. 让我们不要改变原始输入数据,使用自定义程序克隆它,并在自定义程序中拒绝不需要的东西(如果它们存在),以便按预期获得更清晰的克隆输出。 You can use lodash#cloneDeepWith 你可以使用lodash#cloneDeepWith

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

This is just an example of having (hard coded) of what you want to reject. 这只是您想要拒绝(硬编码)的一个例子。 but you can wrap this in a call back and take the reject criteria as an argument to make it dynamic. 但是你可以在回调中包装它并将拒绝标准作为参数使其成为动态的。

So here we go: 所以我们走了:

 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> 

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

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