英文:
How to remove specific nested object from array of arrays
问题
如何从对象数组中删除一个项目:
[
{
"category": "CC",
"paymentOptions": [
{
"payCode": "v",
"description": "Visa"
},
{
"payCode": "m",
"description": "Master"
}
]
},
{
"category": "PayPal",
"paymentOptions": [
{
"payCode": "PY",
"description": "Paypal"
}
]
}
]
我想从上述对象数组中删除这个部分:
{
"payCode": "m",
"description": "Master"
}
删除上述部分后,我的数组应该如下所示:
[
{
"category": "CC",
"paymentOptions": [
{
"payCode": "v",
"description": "Visa"
}
]
},
{
"category": "PayPal",
"paymentOptions": [
{
"payCode": "PY",
"description": "Paypal"
}
]
}
]
我尝试了下面的代码,但没有返回期望的结果:
this.payments.filter(x => x.paymentOptions.filter(x => x.description.toLowerCase() != "Master"))
如何做到这一点?我需要在删除特定对象后得到上述输出。
英文:
How to remove an item from an array of objects:
[
{
"category": "CC",
"paymentOptions": [
{
"payCode": "v",
"description": "Visa"
},
{
"payCode": "m",
"description": "Master"
}
]
},
{
"category": "PayPal",
"paymentOptions": [
{
"payCode": "PY",
"description": "Paypal"
}
]
}
]
I want to remove this section from the above array of objects:
{
"payCode": "m",
"description": "Master"
}
After removing the above section my array should be like:
[
{
"category": "CC",
"paymentOptions": [
{
"payCode": "v",
"description": "Visa"
}
]
},
{
"category": "PayPal",
"paymentOptions": [
{
"payCode": "PY",
"description": "Paypal"
}
]
}
]
I have tried the below code but does not return the desired result:
this.payments.filter(x => x.paymentOptions.filter(x => x.description.toLowerCase() !="Master"))
How to do that? I need the output as above after removing the specific object.
答案1
得分: 1
你正在尝试从payments
数组的每个元素中删除paymentOptions
数组中description
为"master"的项目。
-
使用
x.description.toLowerCase() != "Master"
,这将永远不会为true
。 -
使用
Array.map()
迭代并更新每个元素的paymentOptions
数组。
let result = this.payments.map(x => ({
...x,
paymentOptions: x.paymentOptions.filter(y => y.description.toLowerCase() != "master")
}));
英文:
You are trying to remove the item with description
: "master" in paymentOptions
array for each element in the payments
array.
-
With
x.description.toLowerCase() !="Master"
, this will be never betrue
. -
Use the
Array.map()
to iterate and update thepaymentOptions
array for each element.
let result = this.payments.map(x => ({
...x,
paymentOptions: x.paymentOptions.filter(y => y.description.toLowerCase() != "master")
}));
答案2
得分: 0
你的代码中有多个错误:
- 你没有获取到第一个filter调用的结果:
filter
返回一个数组,并且不会修改原始数组。你必须获取结果,例如this.payments = this.payments.filter(...);
- 将一个filter调用作为另一个filter调用的条件可能不起作用,这里需要一个条件,并且filter返回一个始终为真值的数组。内部filter调用的结果也不会被存储。
- 你使用toLowerCase并与大写的"Master"进行比较,所以每个元素都会通过这个测试。
你可以尝试使用map
和filter
的组合,像这样:
this.payments = [
{
"category": "CC",
"paymentOptions": [
{
"payCode": "v",
"description": "Visa"
},
{
"payCode": "m",
"description": "Master"
}
]
},
{
"category": "PayPal",
"paymentOptions": [
{
"payCode": "PY",
"description": "Paypal"
}
]
}
];
var result = this.payments.map(a => {
a.paymentOptions = a.paymentOptions.filter( x => x.description.toLowerCase() != 'master' );
return a;
});
console.log(result);
英文:
There are multiple mistakes in your code:
- Your first call to filter's result is not retreived:
filter
returns an array and doesn't modify the original array. You must get the result, for examplethis.payments = this.payments.filter(...);
- using a filter call as test for another filter call will probably not work, a condition is expected here, and filter returns an array which is always truthy. The result of the inner filter call will also not be stored
- you use toLowerCase and compare to "Master" which is capitalized, so every element will pass this test
You can try a combination of map
and filter
like this
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
this.payments = [
{
"category": "CC",
"paymentOptions": [
{
"payCode": "v",
"description": "Visa"
},
{
"payCode": "m",
"description": "Master"
}
]
},
{
"category": "PayPal",
"paymentOptions": [
{
"payCode": "PY",
"description": "Paypal"
}
]
}
];
var result = this.payments.map(a => {
a.paymentOptions = a.paymentOptions.filter( x => x.description.toLowerCase() != 'master' );
return a;
});
console.log(result);
<!-- end snippet -->
答案3
得分: 0
如果你不再需要"原始"数组,你可以简单地使用forEach方法:
this.payments.forEach(x => {
paymentOptions: x.paymentOptions
.filter(y => y.description.toLowerCase() != "master")
});
英文:
If you don't want any more the "original" array, you can simple use forEach
this.payments.forEach(x => {
paymentOptions: x.paymentOptions
.filter(y => y.description.toLowerCase() != "master")
});
答案4
得分: 0
由于某种原因,所有其他答案都建议使用array = array.filter(…)
的方法。
然而,还有许多其他方法,其中之一是实际上“查找”并实际上“删除”不需要的项(而不是用不需要的项替换原始数组)。因此,重要的是,这种方法会改变原始值。
interface Item {
category: string
paymentOptions: Array<{
payCode: string
description: string
}>
}
function removePaymentOptions(category: string, payCode: string, items: Item[]): void {
// 找到要更新的项
const itemsToUpdate = items.filter((item) => item.category === category)
// 在每个项中找到不需要的付款选项
for (const item of itemsToUpdate) {
const optionIndex = item.paymentOptions.findIndex((option) => option.payCode === payCode)
// 如果付款选项存在,则从项中删除它
if (optionIndex !== -1) {
item.paymentOptions.splice(optionIndex, 1)
}
}
}
const items = /* 你的数组 */
removePaymentOptions('CC', 'm', items)
// `items` 现在已更新为不包含不需要的付款选项
英文:
For some reason, all other answers suggest array = array.filter(…)
approach.
There are many other approaches though, and one of them would be to actually find and actually remove the undesired items (rather than substitute the original array with a new one that doesn't have the undesired items). So, importantly, this approach changes the original value.
interface Item {
category: string
paymentOptions: Array<{
payCode: string
description: string
}>
}
function removePaymentOptions(category: string, payCode: string, items: Item[]): void {
// find the to-be-updated items
const itemsToUpdate = items.filter((item) => item.category === category)
// find the undesired payment options in each of the item
for (const item of itemsToUpdate) {
const optionIndex = item.paymentOptions.findIndex((option) => option.payCode === payCode)
// if the payment option exists, remove it from the item
if (optionIndex !== -1) {
item.paymentOptions.splice(optionIndex, 1)
}
}
}
const items = /* your array */
removePaymentOptions('CC', 'm', items)
// `items` is now updated to _not_ have the undesired payment options
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论