#javascript #arrays
#javascript #массивы
Вопрос:
У меня есть массив объектов:
И я хочу удалить объект, который имеет определенную дату (2020-09-24 в этом примере) в массиве excluded_dates, чтобы вывести новый массив следующим образом:
outcome = [
{
title: '"test1"',
excluded_dates: false,
},
{
title: '"test2"',
excluded_dates: [
{ excluded_date: "2020-09-12" },
{
excluded_date: "2020-09-17",
},
],
}
];
Для этого я думал об использовании двойной фильтрации. Я также пробовал some() , но это для массивов, а не для массива объектов.
const data = [
{
title: '"test1"',
excluded_dates: false,
},
{
title: '"test2"',
excluded_dates: [
{ excluded_date: "2020-09-12" },
{
excluded_date: "2020-09-17",
},
],
},
{
title: '"test3"',
excluded_dates: [
{
excluded_date: "2020-09-16",
},
{
excluded_date: "2020-09-24",
},
],
},
];
const outcome = data.filter(function (event) {
if (event.excluded_dates) {
return event.excluded_dates.filter(
(date) => date.excluded_date === "2020-09-24"
);
}
});
console.log(outcome);
Это, конечно, работает не так, как ожидалось. Чего мне здесь не хватает?
Ответ №1:
Обязательно возвращайте true
, если у объекта нет excluded_dates
свойства. Кроме того, поскольку вы ищете только одну дату, вы можете заменить свое второе использование Array.prototype.filter
на Array.prototype.some()
const outcome = data.filter((event) => {
return !(
event.excluded_dates amp;amp; // if there is no `excluded_dates` property, return `true`
event.excluded_dates.some( // otherwise, try to find the date. if found, return `false`
({ excluded_date }) => excluded_date === "2020-09-24"
)
);
});
Пример фрагмента кода:
const data = [{
title: '"test1"',
excluded_dates: false,
},
{
title: '"test2"',
excluded_dates: [{
excluded_date: "2020-09-12"
},
{
excluded_date: "2020-09-17",
},
],
},
{
title: '"test3"',
excluded_dates: [{
excluded_date: "2020-09-16",
},
{
excluded_date: "2020-09-24",
},
],
},
];
const outcome = data.filter((event) => {
return !(
event.excluded_dates amp;amp;
event.excluded_dates.some(
({ excluded_date }) => excluded_date === "2020-09-24"
)
);
});
console.log(outcome);
Комментарии:
1. Это работает, но можете ли вы объяснить, что делает этот код? У вас есть сокращение, чтобы проверить, существуют ли excluded_dates , но почему вы возвращаете true для else ?
2.
Array.prototype.filter()
запускает заданную функцию через каждый элемент массива. Если функция вернетсяtrue
, она сохранит элемент в массиве. В противном случае он удалит его из массива.
Ответ №2:
Я бы использовал filter
:
let data = [
{ index: 0, exclude: ['Monday'] },
{ index: 1, exclude: ['Tuesday', 'Thursday'] },
{ index: 2, exclude: ['Wednesday'] },
];
data = data.filter(el => !el.exclude.includes('Tuesday'));
console.log(data);
// data = { index: 0, exclude: ['Monday'] }, { data: 2, exclude: ['Wednesday'] }
Ответ №3:
Верните true
, если событие не excluded_dates
имеет свойства, потому что те, которые вы захотите сохранить в каждом сценарии.
Вместо вложенного фильтра проверьте excluded_date
, не равно ли каждое значение в excluded_dates
массиве "2020-09-24"
с Array.prototype.every
помощью метода, который возвращает true или false на основе того, оценивается ли каждый обратный вызов true или нет.
const data = [{
title: '"test1"',
excluded_dates: false,
},
{
title: '"test2"',
excluded_dates: [{
excluded_date: "2020-09-12"
},
{
excluded_date: "2020-09-17",
},
],
},
{
title: '"test3"',
excluded_dates: [{
excluded_date: "2020-09-16",
},
{
excluded_date: "2020-09-24",
},
],
},
];
const outcome = data.filter(function(event) {
if (event.excluded_dates) {
return event.excluded_dates.every(
(date) => date.excluded_date !== "2020-09-24"
);
}
return true;
});
console.log(outcome);
Ответ №4:
вы были на правильном пути, нужно только изменить условие. Фильтр всегда возвращает элемент, условие которого соответствует. вам нужно проверить, является ли значение excluded_date ложным или массив excluded_date не содержит даты. Итак, во внутреннем фильтре, если мы получаем длину 0, это означает, что date отсутствует в массиве и поэтому включается в ожидаемый результат.
const data = [{
title: '"test1"',
excluded_dates: false,
},
{
title: '"test2"',
excluded_dates: [{
excluded_date: "2020-09-12"
},
{
excluded_date: "2020-09-17",
},
],
},
{
title: '"test3"',
excluded_dates: [{
excluded_date: "2020-09-16",
},
{
excluded_date: "2020-09-24",
},
],
},
];
const outcome = data.filter(event => (!event.excluded_dates || event.excluded_dates.filter(
(date) => date.excluded_date === "2020-09-24"
).length == 0))
console.log(outcome);
Ответ №5:
Вы были на правильном пути. Вы даже можете использовать some() для массива excluded_dates . Вот рабочая функция
data.filter((d) => {
if (Array.isArray(d.excluded_dates)) {
return d.excluded_dates.some((date) => date.excluded_date === '2020-09-24');
}
return true;
});
Ответ №6:
Пробовал использовать операторы Foreach и filter
const data = [
{
title: '"test2"',
excluded_dates: [
{ excluded_date: "2020-09-12" },
{
excluded_date: "2020-09-17",
},
],
},
{
title: '"test3"',
excluded_dates: [
{
excluded_date: "2020-09-16",
},
{
excluded_date: "2020-09-24",
},
],
},
];
data.forEach(function(item, idx) {
item.excluded_dates.filter(function(item1) {
if( item1.excluded_date === "2020-09-24" ) {
return data.pop(idx);
}
});
});
console.log(data);