Как использовать метод find () для вложенных массивов? - PullRequest
1 голос
/ 16 марта 2019

В этом примере вы можете видеть, что метод find отлично работает в этом массиве:

var inventory = [
    {name: 'apples', quantity: 2},
    {name: 'bananas', quantity: 0},
    {name: 'cherries', quantity: 5}
];


console.log(inventory.find(fruit => fruit.name === 'cherries')); 
// { name: 'cherries', quantity: 5 }

Как только я добавляю еще один уровень и пытаюсь найти в нем предмет, он просто не находит его, он показывает неопределенное:

var inventory = [
    {name: 'apples', quantity: 2},
    {name: 'bananas', quantity: 0},
    {name: 'cherries', quantity: 5, type: [
       {name: 'rainier', quantity: 3},
       {name: 'bing', quantity: 2}
     ]}
];


console.log(inventory.find(fruit => fruit.name === 'bing')); 
// undefined
// should be: { name: 'bing', quantity: 2 }

Так что, я думаю, есть какой-то другой способ сделать это, но я этого не знаю и ничего не могу найти.

Ответы [ 4 ]

1 голос
/ 16 марта 2019

inventory.find найдет только элемент массива с заданными условиями в inventory и потому что {name: 'bing', quantity: 2} отсутствует в inventory, поэтому он вернет undefined
.Вы можете сделать это, используя рекурсию

.

var inventory = [
    {name: 'apples', quantity: 2},
    {name: 'bananas', quantity: 0},
    {name: 'cherries', quantity: 5, type: [
       {name: 'rainier', quantity: 3},
       {name: 'bing', quantity: 2}
     ]}
];

function findFruitWithName(arr,name){
  let x = arr.find(fruit => fruit.name === name);
  if(x === undefined){
    for(let fruit of arr){
      if(fruit.type) {
        let y = findFruitWithName(fruit.type,name);
        if(y !== undefined) return y
      }
    }
  }
  else return x;
}


console.log(findFruitWithName(inventory,'bing'))
// undefined
// should be: { name: 'bing', quantity: 2 }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
1 голос
/ 16 марта 2019

Вы правы в том, что find смотрит только на элементы в массиве и не смотрит на вложенные, поэтому вы должны создать свои собственные.

Вы можете перебрать все элементы в inventory и собрать все элементы в потенциальных type массивах и продолжать зацикливать их, пока не найдете элемент с желаемым name или вернуть undefined если вы проверите все пункты и не найдете соответствия.

Пример

const inventory = [
  { name: "apples", quantity: 2 },
  { name: "bananas", quantity: 0 },
  {
    name: "cherries",
    quantity: 5,
    type: [{ name: "rainier", quantity: 3 }, { name: "bing", quantity: 2 }]
  }
];

function findItem(inventory, name) {
  let items = [...inventory];
  let item;

  while (items.length !== 0) {
    item = items.pop();
    if (item.name === name) {
      return item;
    } else if (item.type) {
      items.push(...item.type);
    }
  }

  return undefined;
}

console.log(findItem(inventory, "bing"));
1 голос
/ 16 марта 2019

Ваш код не позволяет использовать необязательный массив type.Предполагая, что вы хотите выполнить поиск в глубину, вы сделаете обратный вызов именованной функцией и будете использовать ее рекурсивно, см. Комментарии:

var inventory = [
    {name: 'apples', quantity: 2},
    {name: 'bananas', quantity: 0},
    {name: 'cherries', quantity: 5, type: [
       {name: 'rainier', quantity: 3},
       {name: 'bing', quantity: 2}
    ]}
];

// Define the function
function find(array, name) {
    // Loop the entries at this level
    for (const entry of array) {
        // If we found it, return it
        if (entry.name === name) {
            return entry;
        }
        // If not but there's a type array, recursively search it
        if (Array.isArray(entry.type)) {
            const found = find(entry.type, name);
            if (found) {
                // Recursive search found it, return it
                return found;
            }
        }
    }
    // If execution falls off the end, it's effectively `return undefined;`
}
console.log(find(inventory, 'bing')); 
0 голосов
/ 16 марта 2019

попробуйте

var inventory = [
    {name: 'apples', quantity: 2},
    {name: 'bananas', quantity: 0},
    {name: 'cherries', quantity: 5, type: [
       {name: 'rainier', quantity: 3},
       {name: 'bing', quantity: 2}
     ]}
];
var name = 'bing'
var result = inventory.find((fruit) => {
  if(fruit.name === name) return true
  if(fruit.type) return fruit.type.find(type=>type.name===name) 
  return false
})
console.log(result)

UPDATE: если вы хотите сделать его рекурсивным, вы можете попробовать

функция поиска (имя, инвентарь) {

 return inventory.find((fruit) => {
  if(fruit.name === name) return true
  if(fruit.type) return find(name, fruit.type)
  return false
}) 
}
console.log(find(name,inventory))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...