Удалить объекты из вложенного массива с помощью Lodash - PullRequest
1 голос
/ 24 февраля 2020

У меня следующая структура JSON:

{
  "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"
        }
      ]
    }
  ]
}

Я хочу удалить все товары из каждого магазина, в котором товар не обладает определенными свойствами.

Если я скрываю его в плоская карта, тогда я могу сделать это нормально, но тогда я теряю внешний объект, так как у меня просто есть массив со всеми продуктами, которые не были удалены.

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

Я попробовал следующее, но просто в итоге получается пустой массив:

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

Я также пытался использовать _.reduce() и _.transform(), но не могу заставить его работать

Финальный JSON должен выглядеть следующим образом:

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

1 Ответ

3 голосов
/ 24 февраля 2020

Вам не нужна вода sh для этого. Вы можете просто использовать Array.prototype.map и Array.protype.filter (а также некоторые spread syntax для поверхностного объединения свойств объекта):

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);

РЕДАКТИРОВАТЬ: Как @Deykun указал , если вы хотите игнорировать магазины, в которых нет активных продуктов, Вы можете отфильтровать магазины, используя Array.prototype.some в 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);
...