如何从数组中删除特定的嵌套对象?

huangapple go评论94阅读模式
英文:

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"的项目。

  1. 使用x.description.toLowerCase() != "Master",这将永远不会为true

  2. 使用Array.map()迭代并更新每个元素的paymentOptions数组。

let result = this.payments.map(x => ({
  ...x,
  paymentOptions: x.paymentOptions.filter(y => y.description.toLowerCase() != "master")
}));

在TypeScript Playground上查看演示

英文:

You are trying to remove the item with description: "master" in paymentOptions array for each element in the payments array.

  1. With x.description.toLowerCase() !="Master", this will be never be true.

  2. Use the Array.map() to iterate and update the paymentOptions array for each element.

let result = this.payments.map(x => ({
  ...x,
  paymentOptions: x.paymentOptions.filter(y => y.description.toLowerCase() != "master")
}));

Demo @ TypeScript Playground

答案2

得分: 0

你的代码中有多个错误:

  • 你没有获取到第一个filter调用的结果:filter返回一个数组,并且不会修改原始数组。你必须获取结果,例如this.payments = this.payments.filter(...);
  • 将一个filter调用作为另一个filter调用的条件可能不起作用,这里需要一个条件,并且filter返回一个始终为真值的数组。内部filter调用的结果也不会被存储。
  • 你使用toLowerCase并与大写的"Master"进行比较,所以每个元素都会通过这个测试。

你可以尝试使用mapfilter的组合,像这样:

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 example this.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 = [
  {
    &quot;category&quot;: &quot;CC&quot;,
    &quot;paymentOptions&quot;: [
        {
            &quot;payCode&quot;: &quot;v&quot;,
            &quot;description&quot;: &quot;Visa&quot;
        },
        {
            &quot;payCode&quot;: &quot;m&quot;,
            &quot;description&quot;: &quot;Master&quot;
        }
    ]
  },
  {
    &quot;category&quot;: &quot;PayPal&quot;,
    &quot;paymentOptions&quot;: [
        {
            &quot;payCode&quot;: &quot;PY&quot;,
            &quot;description&quot;: &quot;Paypal&quot;
        }
    ]
  }
];

var result = this.payments.map(a =&gt; {
  a.paymentOptions = a.paymentOptions.filter( x =&gt; x.description.toLowerCase() != &#39;master&#39; );
  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 =&gt; {
  paymentOptions: x.paymentOptions
           .filter(y =&gt; y.description.toLowerCase() != &quot;master&quot;)
});

答案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&lt;{
    payCode: string
    description: string
  }&gt;
}

function removePaymentOptions(category: string, payCode: string, items: Item[]): void {
  // find the to-be-updated items
  const itemsToUpdate = items.filter((item) =&gt; item.category === category)

  // find the undesired payment options in each of the item
  for (const item of itemsToUpdate) {
    const optionIndex = item.paymentOptions.findIndex((option) =&gt; 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(&#39;CC&#39;, &#39;m&#39;, items)

// `items` is now updated to _not_ have the undesired payment options

huangapple
  • 本文由 发表于 2023年7月27日 17:21:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76778282.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定