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

时间:2018-10-25 05:20:44

标签: javascript arrays json reactjs lodash

我要删除每个部分下唯一的低级对象(例如,在下面的代码中,在个人数据下有两个对象...我要删除一个对象,其中“ action”:旧),其中“ action”: “旧”

我在项目中使用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"
        }
      ]
    }
  }
]

很抱歉,您的演讲不正确,这是我第一次发布问题

7 个答案:

答案 0 :(得分: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);
     }
   }
 }
}

答案 1 :(得分: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
        }
      });
    });
  });
});

答案 2 :(得分:1)

您可以通过不带破折号的方式实现此目的:

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

答案 3 :(得分: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))

答案 4 :(得分: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));

答案 5 :(得分: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>

答案 6 :(得分:0)

我们不要突变原始输入数据,而是使用定制器对其进行克隆,并拒绝定制器中不需要的东西(如果存在)以按预期方式获得更清晰的克隆输出。您可以使用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>