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