Я пытаюсь отфильтровать объект JSON, не являющийся массивом, как следующий фрагмент
const filter = { filterRows: ['one'] };
const templateMapper = {
'one': {
title: 'one',
},
'two': {
title: 'two',
},
'three': {
title: 'three',
},
}
const filterDialogView = filter.filterRows;
const filterTemplateMapper = [templateMapper].filter(row => !filterDialogView.includes(row));
console.info(filterTemplateMapper);Но это не фильтрация
Я получаю следующий вывод
[
{
"one": {
"title": "one"
},
"two": {
"title": "two"
},
"three": {
"title": "three"
}
}
]
Выход желания
{
"two": {
"title": "two"
},
"three": {
"title": "three"
}
}
Я хочу отфильтровать строку на основе filterRows, например, если filterRows содержит one, как указано выше, JSON, тогда one следует удалить из templateMapper
я использую [templateMapper], см. приведенный выше код, который я использовал [] массивы
Да, но в этом массиве одна запись — объект ВЕСЬ.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Один из вариантов — создать копию объекта templateMapper, затем выполнить итерацию по filterRows и удалить каждый связанный ключ:
const filter = {
filterRows: ['one']
};
const templateMapper = {
'one': {
title: 'one',
},
'two': {
title: 'two',
},
'three': {
title: 'three',
},
};
const filterTemplateMapper = { ...templateMapper };
filter.filterRows.forEach((key) => {
delete filterTemplateMapper[key];
});
console.info(filterTemplateMapper);(также, как примечания к комментариям, Не существует такого понятия, как «объект JSON».)
Это изменяет объект, а не создает новый, что отличается от того, как работает метод фильтра.
Он не изменяет исходный объект — { ...templateMapper } создает копию.
Вы можете сначала filterentries объекта. Затем используйте Object.fromEntries(), чтобы создать новый объект из этих отфильтрованных записей.
const filter = { filterRows: ['one'] };
const templateMapper = {
'one': {
title: 'one',
},
'two': {
title: 'two',
},
'three': {
title: 'three',
},
}
const filteredObject = Object.fromEntries(
Object.entries(templateMapper).filter(([k]) => !filter.filterRows.includes(k))
)
console.info(filteredObject)Вы можете filter() объекты. Вы должны filter() записи объекта, а затем снова преобразовать его в объект, используя Object.fromEntries()
const filter = { filterRows: ['one'] };
const templateMapper = { 'one': { title: 'one', }, 'two': { title: 'two', }, 'three': { title: 'three', }, }
const filterDialogView = filter.filterRows;
const filterTemplateMapper = Object.fromEntries(
Object.entries(templateMapper)
.filter(row => !filterDialogView.includes(row[0].title))
);
console.info(filterTemplateMapper);Если Object.fromEntries() не поддерживается вашим браузером, используйте reduce()
const filter = { filterRows: ['one'] };
const templateMapper = { 'one': { title: 'one', }, 'two': { title: 'two', }, 'three': { title: 'three', }, }
const filterDialogView = filter.filterRows;
const filterTemplateMapper = Object.entries(templateMapper)
.filter(row =>!filterDialogView.includes(row[0].title))
.reduce((ac,[k,v]) => (ac[k] = v,ac),{});
console.info(filterTemplateMapper);Вы можете использовать Объект.fromEntries для создания объекта из отфильтрованных записей.
Здесь идея: -
const filter = { filterRows: ['one'] };
const template = {'one': {title: 'one',},'two': {title: 'two',},'three': {title: 'three',}}
const filterDialogView = filter.filterRows;
const final = Object.entries(template).filter(([row])=> !filterDialogView.includes(row))
console.info(Object.fromEntries(final));Если ваша среда не поддерживает Object.fromEntries, вы можете использовать это
const filter = { filterRows: ['one'] };
const template = {'one': {title: 'one',},'two': {title: 'two',},'three': {title: 'three',}}
const filterDialogView = filter.filterRows;
const final = Object.entries(template).filter(([row])=> !filterDialogView.includes(row))
const output = final.reduce((op,[key,value])=>{
op[key] = value
return op
},{})
console.info(output);Это лучший ответ (я собирался опубликовать идентичный код) - я бы также добавил несколько замечаний по поводу Object.fromEntries
@JaromandaX, спасибо, приятель :), я добавил описание кода и соответствующую ссылку,
@CodeManiac я получаю эту ошибку Object.fromEntries не является функцией в Node.JS
@ user11229655, какую версию узла вы используете, приятель?
я использую узел v10.15.2
@CodeManiac, который я пробовал в узле REPL.it, кажется, проблема с v10.15.2. также попробовал реагировать, все работает нормально, спасибо
@user11229655 user11229655 я не уверен в совместимости с узлом, если он несовместим с этой версией, вы можете добавить полифилл для Object.fromEntries или использовать reduce для создания объекта
Вместо изменения исходного объекта создайте его копию и удалите ненужные ключи. Для удаления вы можете использовать ключевое слово delete. Повторил массив filterRows, а затем использовал delete для удаления ключей из скопированного объекта.
const filter = {
filterRows: ['one']
};
const templateMapper = {
'one': {
title: 'one',
},
'two': {
title: 'two',
},
'three': {
title: 'three'
},
}
let newObj = JSON.parse(JSON.stringify(templateMapper));
filter.filterRows.forEach(function(item) {
if (newObj.hasOwnProperty(item)) {
delete newObj[item]
}
});
console.info(newObj)Функция filter() доступна только для массивов. Чтобы получить такое же поведение с объектом, вам нужно использовать entries() объекта.
const filter = {
filterRows: ['one']
}
const templateMapper = {
'one': {
title: 'one',
},
'two': {
title: 'two',
},
'three': {
title: 'three',
},
}
const filteredMapper = Object.entries(templateMapper).reduce((acc, [key, value]) => {
// if the key is not in the filtered list, add this entry to the object
if (!filter.filterRows.includes(key)) {
acc[key] = value
}
return acc
}, {}) // pass in empty object as initial value of accumulator
console.info(filteredMapper)Это работает следующим образом: сначала мы получаем entries (пары ключ/значение) из templateMapper. Затем мы берем эти записи и reduce их. Сокращение принимает несколько аргументов, включая «аккумулятор», который собирает поля, которые мы хотим сохранить. Мы «деструктурируем» key и value, чтобы мы могли проверить, есть ли ключ в списке фильтров. Если фильтровать не будем, добавляем из аккумулятора. Затем мы возвращаем аккумулятор для следующей итерации сокращения. Наконец, мы передаем пустой объект в качестве начального значения для аккумулятора на первой итерации.
Вы можете использовать этот способ:
const filter = { filterRows: ['one'] };
const templateMapper = {
'one': {
title: 'one',
},
'two': {
title: 'two',
},
'three': {
title: 'three',
},
}
// Convert object templateMapper to array with key
const keyArrayTemplateMapper = Object.keys(templateMapper);
// Filter key array
const filterKey = keyArrayTemplateMapper.filter(key => !filter.filterRows.includes(key));
// Using reduce method to return new array
const output = filterKey.reduce((obj, key) => {
obj[key] = templateMapper[key];
return obj;
}, {});
console.info(output);Все ответы здесь заминусованы, кроме одного. Попробуйте добавить объяснение кода.
Я не вижу ничего плохого в вашем коде, единственное, чего не хватает, - это какое-то объяснение, приятель, считается хорошей практикой добавить объяснение к вашему ответу, поскольку это поможет будущим читателям.
Я понял, добавил некоторые пояснения. Спасибо вам, ребята.
@Scofield, вы можете сделать свой код исполняемым фрагментом кода читать здесь, и вот ваши награды за подробный ответ
где JSON? все, что я вижу, это объект... и объекты не могут быть отфильтрованы с помощью Array.filter, потому что у объектов нет метода фильтра