[英]Remove nested array object based on id and type?
Given a nested array of meals, we're trying to remove a nested object based on an id
and mealType
combo.给定一组嵌套的餐点,我们尝试基于
id
和餐点类型组合删除嵌套的mealType
。 We start of with 2 nested breakfast
meals, if both are removed, we're trying to remove the parent key completely, since it is now empty.我们从 2 个嵌套
breakfast
开始,如果两者都被删除,我们会尝试完全删除父键,因为它现在是空的。
Here is the code we have so far:这是我们到目前为止的代码:
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);
The thing is we're trying to remove the nested meal object in removeItem
without explicitly passing menuGroupX
, instead, we're trying to target the nested mealsList
object based on the id
and mealType
.问题是我们试图在没有明确传递
menuGroupX
的情况下删除removeItem
中的嵌套餐 object ,相反,我们试图基于id
和 mealType 定位嵌套的mealsList
表mealType
。 The pseudo code is using a *
to show that.伪代码使用
*
来表明这一点。
The console.log
statements show the expected outcome in terms of how the mealsList
should render under them. console.log
语句根据mealsList
应如何呈现的方式显示预期结果。
We're looking for something short and sweet, ideally a one liner, even if that means using a lodash solution for simplicity.我们正在寻找简短而甜蜜的东西,理想情况下是单衬里,即使这意味着为了简单起见使用 lodash 解决方案。
Here is the fiddle (Code In JS tab)这是小提琴(JS标签中的代码)
Any idea what to put instead of the pseudocode in removeItem
to have the mealsList
remove the specific items?知道在
removeItem
中放置什么而不是伪代码来让mealsList
删除特定项目吗?
You can use lodash's _.mapValues()
to map the array keys in your object to exclude any objects which contain the id
and mealType
passed into your function.您可以使用 lodash 的
_.mapValues()
到 map 中的数组键 object 以排除包含传递给您的 ZC1C425268E68385D1AB5074C17A94F1 的id
和mealType
的任何对象You can then use _.omitBy()
to remove any keys which have an empty array as their value:然后,您可以使用
_.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>
A vanilla way could be to first convert your mealsList
into an array of entries, and then filter the inner arrays of the entires with .map()
and .filter()
.一种普通的方法可能是首先将您的
mealsList
转换为条目数组,然后使用.map()
和.filter()
过滤整体的内部 arrays 。 Then, once you're done, you can rebuild the object using Object.fromEntries()
:然后,一旦你完成了,你可以使用
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);
A more browser compatible version of the above (without Object.fromEntries()):上述更兼容浏览器的版本(没有 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);
Ideally, your mealsList
would be an array though, as it is a list , which would make working with your data more straightforward.理想情况下,您的
mealsList
将是一个数组,因为它是一个list ,这将使您的数据处理更加直接。
Here's a pure JavaScript solution which iterates over the keys of mealsList
, filtering by id
and mealType
and then comparing the length of the resultant array to 0;这是一个纯粹的 JavaScript 解决方案,它遍历 mealList 的键,按
id
和mealsList
mealType
,然后将结果数组的长度与 0 进行比较; if it is 0 that key is deleted from mealsList
:如果为 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);
you can do through reduce
and filter
.你可以通过
reduce
和filter
来做。
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.