Я не знаю, как обращаться с вложенными массивами и объектами в JavaScript. Мне нужно проверить, содержит ли какой-либо из заголовков (заголовок основной папки или заголовок в содержимом) определенное слово без учета регистра (информация в образце кода). Он может прекратить проверку, как только найдет слово в любом заголовке. Мне нужно пропустить/игнорировать описание.
const data = [{
"Title": "folder title 1",
"Id": 857412,
"Description": { "Text": "description 1" },
"Contents": [
{ "Title": "contents 1 title 1", "Id": 123456 },
{ "Title": "contents 1 title 2 - Information", "Id": 987654 }
]
},{
"Title": "folder title 2",
"Id": 895623,
"Description": { "Text": "description 2" },
"Contents": [
{ "Title": "contents 2 title 3", "Id": 784512 }
]
}];
const contents = data.map(item => ({Contents:item.Contents}));
const folders = data.map(item => ({Title:item.Title}));
const combinedData = contents.concat(folders);
const stringData = JSON.stringify(combinedData);
console.info(stringData.toLowerCase().includes("information"));
Мой код работает, но я на 100% уверен, что есть лучший способ сделать это, и я не уверен, с каким объемом данных мне придется иметь дело каждый раз. Я просто не могу усвоить массив объектов внутри массива объектов, и я все еще слишком новичок в JavaScript, чтобы понимать многие методы. Примеры на веб-сайтах слишком упрощены: в массиве всего несколько чисел, что не помогает с этими данными.
Какой метод лучше использовать? Как я могу проверить заголовки как для папок, так и для содержимого одновременно, игнорируя при этом описание, без необходимости объединения и преобразования в строки, чтобы найти слово? Спасибо за любые предложения!
@RokoC.Buljan Что не так с JSON.stringify
? Если это решает проблему и работает быстрее, чем другие решения, почему бы и нет?
@RokoC.Buljan Есть .map
. Ключи удалены. ОП написал, код работает правильно
@RokoC.Buljan Это 22 строки кода (5 строк без данных). Как можно было что-то пропустить? Я предполагаю, что вы написали комментарий, не читая код.
Действительно пропустил это, был слишком сосредоточен на этой строке и подумал, что да, все это было преобразовано в строку - и прочитано. И перешел к чтению ответа Бармара. Виноват
Не объединяйте все, просто используйте Array.some()
для поиска соответствующего заголовка в массиве верхнего уровня или во вложенных Contents
массивах. Это прекратится, как только будет найдено совпадение.
function titlesIncludes(data, search) {
search = search.toLowerCase();
return data.some(item =>
item.Title.toLowerCase().includes(search) ||
item.Contents.some(content => content.Title.toLowerCase().includes(search)));
}
console.info(titlesIncludes(data, "information"));
console.info(titlesIncludes(data, "nothing"));
<script>
const data = [{
"Title": "folder title 1",
"Id": 857412,
"Description": {
"Text": "description 1"
},
"Contents": [{
"Title": "contents 1 title 1",
"Id": 123456
},
{
"Title": "contents 1 title 2 - Information",
"Id": 987654
}
]
}, {
"Title": "folder title 2",
"Id": 895623,
"Description": {
"Text": "description 2"
},
"Contents": [{
"Title": "contents 2 title 3",
"Id": 784512
}]
}];
</script>
Хороший ответ Бармара конкретно решает ваш вопрос —
говоря о папках, имеющих содержимое, мы могли бы легко говорить о Узлах дерева.
Помимо файлов, содержимое папки также может легко иметь подпапки и т. д., поэтому вот мои два цента:
создайте рекурсивную функцию, которая проверяет наличие глубоко вложенных узлов
/** Get Contents' node by key value; case-insensitive */
const getNode = (arr = [], prop = "", val = "") => {
for (const node of arr) {
if (node[prop].toLowerCase().includes(val.toLowerCase())) return node;
const res = getNode(node.Contents, prop, val);
if (res) return res;
}
};
// Use like:
console.info(getNode(data, "Title", "information"));
// Or like:
if (getNode(data, "Title", "information")) { console.info("found"); };
Таким образом, вы можете иметь столько вложенных Contents
узлов, сколько захотите.
Как в этом примере:
const data = [{
"Title": "folder title 1",
"Id": 857412,
"Description": {
"Text": "description 1"
},
"Contents": [{
"Title": "contents 1 title 1",
"Id": 123456
},
{
"Title": "contents 1 title 2",
"Id": 987654
}
]
},
{
"Title": "folder title 2",
"Id": 895623,
"Description": {
"Text": "description 2"
},
"Contents": [{
"Title": "contents 2 title 3",
"Id": 784512
}, {
"Title": "SUBFOLDER",
"Id": 999999,
"Contents": [{
"Title": "contents 3 title 3 - Information",
"Id": 987654
}]
}]
}
];
/** Get Contents' node by key value; case-insensitive */
const getNode = (arr = [], prop = "", val = "") => {
for (const node of arr) {
if (node[prop].toLowerCase().includes(val.toLowerCase())) return node;
const res = getNode(node.Contents, prop, val);
if (res) return res;
}
};
console.info(getNode(data, "Title", "information"));
if (getNode(data, "Title", "information")) {
console.info("found");
};
Спасибо, сегодня кое-что узнал....
Какой у вас показатель «лучше»? Как я могу определить, лучше ли один метод, чем другой?