Возвращает дочерний элемент, соответствующий вложенному циклу в JavaScript

#javascript #reactjs #nested-loops

Вопрос:

Я пытаюсь понять, как я могу вернуть ребенка во вложенном цикле в React. Объект данных содержит список документов, каждый из которых содержит список файлов. Это то, что у меня есть до сих пор:

  const match = (data.documents.find((document) =>
        document.files.find(
            (file) => file.fileType === 'pdf',       
        ),
    );
 

Это почти работает, но проблема в том, что здесь соответствие установлено для документа соответствующего файла, и я хочу, чтобы он был обновлен до соответствующего файла .. Есть какие-либо сведения о том, как я могу изменить его, чтобы вместо этого вернуть файловый объект?

Правка: я хочу, чтобы возвращалось только первое совпадение, а затем выходило из циклов.

Комментарии:

1. Вместо поиска вы можете использовать фильтр? Потому что фильтр вернет совпадающие данные.

2. Похоже, что filter() возвращает массив с совпадающими элементами, где я хочу, чтобы возвращалось только первое совпадение .. Так что не думайте, что это сработает так, как задумывалось, но спасибо @AbuSufian

3. Из этого возвращенного массива вы можете выбрать первый элемент !

4. Вот что find делает—возвращает элемент, удовлетворяющий предикату. Если это не то, что вы хотите сделать, то find на самом деле это не лучший вариант; повторение и разбиение, фильтрация и выбор первого и т. Д.-Все это жизнеспособные варианты.

Ответ №1:

Одним из вариантов было бы Array.prototype.flat() сначала использовать, чтобы собрать все ваши файлы в один массив, а затем вызвать Array.prototype.find() его, чтобы получить первое совпадение:

 const documents = [{
  files: [
    { name: 'a.png', fileType: 'png' },
    { name: 'b.png', fileType: 'png' },
    { name: 'c.png', fileType: 'png' },
  ],
}, {
  files: [
    { name: 'd.png', fileType: 'png' },
    { name: 'e.png', fileType: 'png' },
    { name: 'f.pdf', fileType: 'pdf' },
  ],
}, {
  files: [
    { name: 'g.png', fileType: 'png' },
    { name: 'h.pdf', fileType: 'pdf' },
    { name: 'i.png', fileType: 'png' },
  ],
}]

const files = documents.map(doc => doc.files).flat();

console.log(files);

const match = files.find(file => file.fileType === 'pdf');

console.log(match); 
 .as-console-wrapper {
  max-height: 100% !important;
} 

Если вам нужны все соответствующие файлы, используйте Array.prototype.filter() вместо Array.prototype.find() :

 const documents = [{
  files: [
    { name: 'a.png', fileType: 'png' },
    { name: 'b.png', fileType: 'png' },
    { name: 'c.png', fileType: 'png' },
  ],
}, {
  files: [
    { name: 'd.png', fileType: 'png' },
    { name: 'e.png', fileType: 'png' },
    { name: 'f.pdf', fileType: 'pdf' },
  ],
}, {
  files: [
    { name: 'g.png', fileType: 'png' },
    { name: 'h.pdf', fileType: 'pdf' },
    { name: 'i.png', fileType: 'png' },
  ],
}]

const matches = documents.map(doc => doc.files).flat().filter(file => file.fileType === 'pdf');

console.log(matches); 

Комментарии:

1. Ваше первое предложение сработало идеально, спасибо! думаю, мне нужно немного разобраться в методе flat (), который сделал свое дело 😀

Ответ №2:

Ты мог бы сделать это:

 const documents = [{files: [{fileType: 'jpeg'}, {fileType: 'docx'}]}, {files: [{fileType: 'docx'}]}, {files: [{fileType: 'docx'}, {fileType: 'pdf'}]}, {files: [{fileType: 'jpeg'}]}];
let index;
const match = documents.find((document) =>
  document.files.some(
    // store the index of the matched fileType
    (file, i) => file.fileType === 'pdf' ? (index = i, true) : false,       
  ),
);
console.log(match.files[index]); 

Или с базовыми для…

 const documents = [{files: [{fileType: 'jpeg'}, {fileType: 'docx'}]}, {files: [{fileType: 'docx'}]}, {files: [{fileType: 'docx'}, {fileType: 'pdf'}]}, {files: [{fileType: 'jpeg'}]}];
let matchBreak;

Doc: for(let document of documents) {
  for(let file of document.files) {
    if(file.fileType === 'pdf') {
     matchBreak = file;
     break Doc;
    }
  }
}

console.log(matchBreak);

function findFile(documents) {
  for(let document of documents) {
    for(let file of document.files) {
      if(file.fileType === 'pdf') {
       return file;
      }
    }
  }
}

const matchReturn = findFile(documents);
console.log(matchReturn);