Запрос массива объектов в JavaScipt, соответствующих нескольким критериям - PullRequest
0 голосов
/ 29 октября 2019

Я пытаюсь запросить массив объектов в JavaScript и вернуть объекты, которые соответствуют определенным критериям фильтра.

Мне удалось - благодаря помощи других -фильтровать простой объект, но теперь мне нужно применить то же самое к более сложному объекту.

  // Simple object query:

  var recipes = {
    'soup': {'ingredients': ['carrot', 'pepper', 'tomato']}, 
    'pie': {'ingredients': ['carrot', 'steak', 'potato']}, 
    'stew': {'ingredients': ['steak', 'pepper', 'tomato']}
  };

  var shoppingList = ['carrot', 'steak', 'tomato', 'pepper']

  var result = Object.entries(recipes)//1. get the key-value pairs
    .filter(([key, {ingredients}]) => ingredients.every(t =>       shoppingList.includes(t))) //2. filter them
    .map(([key]) => key) //3. get the keys only

  console.log(result);

  // More complex object:

  var itemsTest = [
    {
      uid: 1,
      items: [
        { item: { uid: "a" } },
        { item: { uid: "b" } },
        { item: { uid: "g" } }
      ]
    },
    {
      uid: 2,
      items: [
        { item: { uid: "b" } },
        { item: { uid: "q" } },
        { item: { uid: "f" } }
      ]
    },
    }
  ];

  var filter = ["b", "q", "f"]

  // Expect filter to return {uid: 2, items}
  }

Фильтр рецептов отлично работает. Но теперь у меня есть более сложный массив объектов, кажется, что тот же подход невозможен.

Я хочу отфильтровать itemsTest в соответствии с uid каждого элемента в массиве items. Я был бы счастлив использовать lodash, если это облегчит жизнь.

Я пытался сгладить массив объектов, используя Object.entries(), но безрезультатно.

  var flattened = objectMap(itemsList, function(value) {
    return Object.entries(value);
  });

  var result = flattened.filter(([key, { uid }]) =>
      uid.every(t => filter.includes(t))
    )

Я также пыталсяупрощенный подход - фильтрация с одним значением - с использованием Array.filter.prototype(), который тоже не работает:

var newArray = flattened.filter(function(el) {
  return el.uid <= 2
});
console.log(newArray)

Любая помощь в понимании навигации по объекту, подобному этому, была бы полезной.

1 Ответ

0 голосов
/ 29 октября 2019

Вы можете использовать Array.find() (или Array.filter() для итерации массива объектов. Теперь используйте Array.every(), и для каждого элемента проверьте, включен ли он uid в массив filter.

const itemsTest = [{"uid":1,"items":[{"item":{"uid":"a"}},{"item":{"uid":"b"}},{"item":{"uid":"g"}}]},{"uid":2,"items":[{"item":{"uid":"b"}},{"item":{"uid":"q"}},{"item":{"uid":"f"}}]}];

const filter = ["b", "q", "f"];

const result = itemsTest.find(({ items }) => // use filter instead of find to get multiple items
  items.every(o => filter.includes(o.item.uid))
);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
...