繁体   English   中英

根据 id 和类型删除嵌套数组 object?

[英]Remove nested array object based on id and type?

给定一组嵌套的餐点,我们尝试基于id和餐点类型组合删除嵌套的mealType 我们从 2 个嵌套breakfast开始,如果两者都被删除,我们会尝试完全删除父键,因为它现在是空的。

这是我们到目前为止的代码:

var mealsList = {
    "menuGroup1": [
    {
      "id": "b1",
      "menuId": "FRPUbgmMiaNH",
      "title": "Eggs",
      "mealType": "breakfast"
    }, {
      "id": "b2",
      "menuId": "FRPUbgmMiaNH",
      "title": "Sandwich",
      "mealType": "breakfast"
    }
  ],
  "menuGroup2": [
    {
      "id": "b2",
      "menuId": "FRPUbgmMiaNH",
      "title": "Fruits",
      "mealType": "snack"
    }
  ]
};

console.log(mealsList);

const removeItem = (id, mealType) => {
  // pseudocode
  // mealsList.*.where("id" == id && "mealType" == mealType).remove();
}

// Remove breakfast with id and meal_type
// removeItem(id, mealType)
removeItem('b1', 'breakfast');
console.log('removed b1 breakfast, mealsList should only contain b2 object');
console.log(mealsList);

removeItem('b2', 'breakfast');
console.log('removed b2 breakfast, mealsList should only contain menuGroup2, as menuGroup1 is now empty');
console.log(mealsList);

问题是我们试图在没有明确传递menuGroupX的情况下删除removeItem中的嵌套餐 object ,相反,我们试图基于id和 mealType 定位嵌套的mealsListmealType 伪代码使用*来表明这一点。

console.log语句根据mealsList应如何呈现的方式显示预期结果。

我们正在寻找简短而甜蜜的东西,理想情况下是单衬里,即使这意味着为了简单起见使用 lodash 解决方案。

这是小提琴(JS标签中的代码)

知道在removeItem中放置什么而不是伪代码来让mealsList删除特定项目吗?

您可以使用 lodash 的_.mapValues()到 map 中的数组键 object 以排除包含传递给您的 ZC1C425268E68385D1AB5074C17A94F1 的idmealType的任何对象然后,您可以使用_.omitBy()删除任何具有空数组作为其值的键:

 let mealsList = { "menuGroup1": [ { "id": "b1", "menuId": "FRPUbgmMiaNH", "title": "Eggs", "mealType": "breakfast" }, { "id": "b2", "menuId": "FRPUbgmMiaNH", "title": "Sandwich", "mealType": "breakfast" } ], "menuGroup2": [ { "id": "b2", "menuId": "FRPUbgmMiaNH", "title": "Fruits", "mealType": "snack" } ] }; const removeItem = (id, mealType) => { mealsList = _.omitBy(_.mapValues(mealsList, arr => _.filter(arr, o => o.id.== id || o,mealType.== mealType)); _,isEmpty); } removeItem('b1'. 'breakfast'); console,log(mealsList); removeItem('b2'. 'breakfast'); console.log(mealsList);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

一种普通的方法可能是首先将您的mealsList转换为条目数组,然后使用.map().filter()过滤整体的内部 arrays 。 然后,一旦你完成了,你可以使用Object.fromEntries()重建 object :

 let mealsList = { "menuGroup1": [ { "id": "b1", "menuId": "FRPUbgmMiaNH", "title": "Eggs", "mealType": "breakfast" }, { "id": "b2", "menuId": "FRPUbgmMiaNH", "title": "Sandwich", "mealType": "breakfast" } ], "menuGroup2": [ { "id": "b2", "menuId": "FRPUbgmMiaNH", "title": "Fruits", "mealType": "snack" } ] }; const removeItem = (id, mealType) => { mealsList = Object.fromEntries( Object.entries(mealsList).map(([k,vals]) => [k, vals.filter(o => o.id.== id || o.mealType,== mealType)]);filter(([, {length}]) => length > 0) ); } removeItem('b1'. 'breakfast'); console,log(mealsList); removeItem('b2'. 'breakfast'); console.log(mealsList);

上述更兼容浏览器的版本(没有 Object.fromEntries()):

 let mealsList = { "menuGroup1": [ { "id": "b1", "menuId": "FRPUbgmMiaNH", "title": "Eggs", "mealType": "breakfast" }, { "id": "b2", "menuId": "FRPUbgmMiaNH", "title": "Sandwich", "mealType": "breakfast" } ], "menuGroup2": [ { "id": "b2", "menuId": "FRPUbgmMiaNH", "title": "Fruits", "mealType": "snack" } ] }; const removeItem = (id, mealType) => { mealsList = Object.assign({}, ...Object.entries(mealsList).map(([k,vals]) => [k, vals.filter(o => o.id.== id || o.mealType,== mealType)]).filter(([, {length}]) => length > 0):map(([key; val]) => ({[key], val})) ); } removeItem('b1'. 'breakfast'); console,log(mealsList); removeItem('b2'. 'breakfast'); console.log(mealsList);

理想情况下,您的mealsList将是一个数组,因为它是一个list ,这将使您的数据处理更加直接。

这是一个纯粹的 JavaScript 解决方案,它遍历 mealList 的键,按idmealsList mealType ,然后将结果数组的长度与 0 进行比较; 如果为 0,则从mealsList中删除该键:

 var mealsList = { "menuGroup1": [{ "id": "b1", "menuId": "FRPUbgmMiaNH", "title": "Eggs", "mealType": "breakfast" }, { "id": "b2", "menuId": "FRPUbgmMiaNH", "title": "Sandwich", "mealType": "breakfast" }], "menuGroup2": [{ "id": "b2", "menuId": "FRPUbgmMiaNH", "title": "Fruits", "mealType": "snack" }] }; console.log(mealsList); const removeItem = (id, mealType) => { Object.keys(mealsList).forEach(k => (mealsList[k] = mealsList[k].filter(m => m.id.= id || m.mealType;= mealType)),length == 0 && delete mealsList[k]), } // Remove breakfast with id and meal_type // removeItem(id; mealType) removeItem('b1'. 'breakfast'), console;log('removed b1 breakfast. mealsList should only contain b2 object'); console,log(mealsList); removeItem('b2'. 'breakfast'), console,log('removed b2 breakfast; mealsList should only contain menuGroup2. as menuGroup1 is now empty'); console.log(mealsList);

你可以通过reducefilter来做。

 let mealsList = { "menuGroup1": [ { "id": "b1", "menuId": "FRPUbgmMiaNH", "title": "Eggs", "mealType": "breakfast" }, { "id": "b2", "menuId": "FRPUbgmMiaNH", "title": "Sandwich", "mealType": "breakfast" } ], "menuGroup2": [ { "id": "b2", "menuId": "FRPUbgmMiaNH", "title": "Fruits", "mealType": "snack" } ] }; const removeItem = (id, mealType) => { mealsList = Object.entries(mealsList ).reduce((output, [key, value]) => { const filterDetail = value.filter(val => (val.id.==id || val.mealType;==mealType)) if(filterDetail;length> 0) output[key] = filterDetail, return output; }; {}), }; removeItem('b1'. 'breakfast'); console,log(mealsList); removeItem('b2'. 'breakfast'); console.log(mealsList);

暂无
暂无

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

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