简体   繁体   中英

Remove objects from nested array using Lodash

I have the following JSON structure:

{
  "id": 123,
  "shops": [
    {
      "shopId": 456,
      "products": [
        {
          "productId": 10001,
          "name": "abc",
          "state": "active"
        },
        {
          "productId": 10002,
          "name": "def",
          "state": "expired"
        }
      ]
    },
    {
      "shopId": 789,
      "products": [
        {
          "productId": 20001,
          "name": "qrt",
          "state": "expired"
        },
        {
          "productId": 20002,
          "name": "jbf",
          "state": "active"
        }
      ]
    }
  ]
}

I want to remove all products from each shop where the product does not have certain properties.

If I covert it to a flat map then I can do it fine, but then I lose the outer object as I just have an array with all the products that haven't been removed in.

_(shopJson.shops).map('products').flatten().map(x => {if(x.state === 'active'){return x}}).compact().value()

I tried the following but just end up with an empty array:

_(shopJson.shops).map('products').filter(x => x.state === 'active').value()

I also tried using _.reduce() and _.transform() but can't get it to work

The final JSON should look like:

{
  "id": 123,
  "shops": [
    {
      "shopId": 456,
      "products": [
        {
          "productId": 10001,
          "name": "abc",
          "state": "active"
        }
      ]
    },
    {
      "shopId": 789,
      "products": [
        {
          "productId": 20002,
          "name": "jbf",
          "state": "active"
        }
      ]
    }
  ]
}

You don't really need lodash for this. You can just use Array.prototype.map and Array.protype.filter (and also some spread syntax to shallow merge object properties):

 const data = {id:123,shops:[{shopId:456,products:[{productId:10001,name:"abc",state:"active"},{productId:10002,name:"def",state:"expired"}]},{shopId:789,products:[{productId:20001,name:"qrt",state:"expired"},{productId:20002,name:"jbf",state:"active"}]}]}; const result = { ...data, shops: data.shops.map((shop) => ({ ...shop, products: shop.products.filter((product) => product.state === 'active'), })), }; console.log(result);

EDIT: As @Deykun pointed out , if you want to ignore shops that don't have any active products, you can filter shops out using Array.prototype.some in a filter :

 const data = {id:123,shops:[{shopId:456,products:[{productId:10001,name:"abc",state:"active"},{productId:10002,name:"def",state:"expired"}]},{shopId:789,products:[{productId:20001,name:"qrt",state:"expired"},{productId:20002,name:"jbf",state:"expired"}]}]}; const result = { ...data, shops: data.shops .filter((shop) => shop.products.some((product) => product.state === 'active')) .map((shop) => ({ ...shop, products: shop.products.filter((product) => product.state === 'active') })) }; console.log(result);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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