У меня проблема с фильтрацией массива в моем файле JSON.
Когда я использую filter
в основном массиве, он работает, но я не могу сделать это в подмассивах.
Это файл JSON:
[
{
"id": 1354,
"name": "name",
"type": "simple",
"status": "ok",
"categories": [
{
"id": 79,
"name": "A",
},
{
"id": 68,
"name": "B",
}
]
},
{
"id": 1368,
"name": "name",
"type": "simple",
"status": "ok",
"categories": [
{
"id": 79,
"name": "A",
},
{
"id": 72,
"name": "C",
}
]
},
{...}
]
Я использую этот код для фильтрации, и он работает как положено и возвращает элементы со status: 'ok'
:
return items.filter( item => {
return item.status == 'ok';
});
То, что я хочу заархивировать, это вернуть элементы, у которых есть category.name: 'B'
.
Этот код работает только с первой категорией, и если первая категория элемента не "B", то этот элемент не отображается:
return items.filter( item => {
for (let category of item.categories) {
return category.name == 'B';
}
});
Спасибо за любые идеи
Попробуйте вместо этого использовать Array.prototype.some()
- он возвращает true
только если некоторые элементы массива удовлетворяют переданному условию.
const whole = [
{
"id": 1354,
"name": "name",
"type": "simple",
"status": "ok",
"categories": [
{
"id": 79,
"name": "A",
},
{
"id": 68,
"name": "B",
}
]
},
{
"id": 1368,
"name": "name",
"type": "simple",
"status": "ok",
"categories": [
{
"id": 79,
"name": "A",
},
{
"id": 72,
"name": "C",
}
]
},
{
"id": 1364,
"name": "name",
"type": "simple",
"status": "ok",
"categories": [
{
"id": 71,
"name": "B",
},
{
"id": 70,
"name": "C",
}
]
},
]
const filtered = whole.filter(level_1 => {
return level_1.categories.some(level_2 => level_2['name'] === 'B')
})
console.log(filtered);
Вы вернулись сразу после первой проверки категории. Вы должны продолжить итерацию, если имя категории не соответствует требуемому шаблону, и возвращать false только после всех итераций.
return items.filter(item => {
for (let category of item.categories) {
if (category.name === 'B') {
return true;
}
}
return false;
});
вы можете использовать Array.prototype.some
чтобы проверить, есть ли у элемента Array.prototype.some
категория
const items = [
{
"id": 1354,
"name": "name",
"type": "simple",
"status": "ok",
"categories": [
{
"id": 79,
"name": "A",
},
{
"id": 68,
"name": "B",
}
]
},
{
"id": 1368,
"name": "name",
"type": "simple",
"status": "ok",
"categories": [
{
"id": 79,
"name": "A",
},
{
"id": 72,
"name": "C",
}
]
}
]
const filtered = items.filter( item => {
return item.categories.some(cat => cat.name === "B");
});
console.log(filtered);
Вы можете сделать что-то вроде этого:
return items.filter( item => {
return item.categories.findIndex(category => category.name === 'B') > -1
});
Вы возвращаетесь слишком рано for
цикла. То, что вы ищете some
- some
:
const res = arr.filter(e => e.categories.some(({name}) => name === 'B'));
console.log(res);
<script>
const arr = [
{
"id": 1354,
"name": "name",
"type": "simple",
"status": "ok",
"categories": [
{
"id": 79,
"name": "A",
},
{
"id": 68,
"name": "B",
}
]
},
{
"id": 1368,
"name": "name",
"type": "simple",
"status": "ok",
"categories": [
{
"id": 79,
"name": "A",
},
{
"id": 72,
"name": "C",
}
]
},
]
</script>
Вы хотите вернуться, только если нашли категорию
return items.filter( item => {
for (let category of item.categories) {
if (category.name === 'B') {
return true
}
}
});
Или другое решение с использованием Array.prototype.some
return items.filter(item => {
return item.categories.some(category => category.name === 'B');
});