Фильтровать массив объектов, чьи свойства содержат значение
Мне интересно, какой самый чистый способ, лучший способ фильтровать массив объектов в зависимости от string keyword
. Поиск должен быть выполнен по любым свойствам объекта.
Когда я набираю lea
, я хочу пройти через все объекты и все их свойства, чтобы вернуть объекты, содержащие lea
Когда я набираю italy
, я хочу пройти через все объекты и все их свойства, чтобы вернуть объекты, содержащие italy
.
Я знаю, что есть много решений, но до сих пор я видел некоторые, для которых вам нужно указать свойство, которое вы хотите сопоставить.
ES6
и lodash
приветствуются!
const arrayOfObject = [{
name: 'Paul',
country: 'Canada',
}, {
name: 'Lea',
country: 'Italy',
}, {
name: 'John',
country: 'Italy',
}, ];
filterByValue(arrayOfObject, 'lea') // => [{name: 'Lea',country: 'Italy'}]
filterByValue(arrayOfObject, 'ita') // => [{name: 'Lea',country: 'Italy'}, {name: 'John',country: 'Italy'}]
Ответы
Ответ 1
Вы можете отфильтровать его и искать только один вхождение строки поиска.
Используемые методы:
function filterByValue(array, string) {
return array.filter(o =>
Object.keys(o).some(k => o[k].toLowerCase().includes(string.toLowerCase())));
}
const arrayOfObject = [{ name: 'Paul', country: 'Canada', }, { name: 'Lea', country: 'Italy', }, { name: 'John', country: 'Italy' }];
console.log(filterByValue(arrayOfObject, 'lea')); // [{name: 'Lea', country: 'Italy'}]
console.log(filterByValue(arrayOfObject, 'ita')); // [{name: 'Lea', country: 'Italy'}, {name: 'John', country: 'Italy'}]
.as-console-wrapper { max-height: 100% !important; top: 0; }
Ответ 2
Хорошо, когда мы уже знаем, что это не будет поиск объекта с помощью методов, мы можем сделать следующее для сохранения бит по временной сложности:
function filterByValue(array, value) {
return array.filter((data) => JSON.stringify(data).toLowerCase().indexOf(value.toLowerCase()) !== -1);
}
Ответ 3
Используйте Object.keys для прокрутки свойств объекта. Используйте сокращение и фильтр, чтобы сделать код более эффективным:
const results = arrayOfObject.filter((obj)=>{
return Object.keys(obj).reduce((acc, curr)=>{
return acc || obj[curr].toLowerCase().includes(term);
}, false);
});
Где термин - ваш поисковый запрос.
Ответ 4
Вы всегда можете использовать array.filter()
а затем array.filter()
каждый объект, и если какое-либо из значений соответствует array.filter()
значению, верните этот объект.
const arrayOfObject = [{
name: 'Paul',
country: 'Canada',
}, {
name: 'Lea',
country: 'Italy',
}, {
name: 'John',
country: 'Italy',
}, ];
let lea = arrayOfObject.filter(function(obj){
//loop through each object
for(key in obj){
//check if object value contains value you are looking for
if(obj[key].includes('Lea')){
//add this object to the filtered array
return obj;
}
}
});
console.log(lea);
Ответ 5
function filterByValue(arrayOfObject,words){
let reg = new RegExp(words,'i');
return arrayOfObject.filter((item)=>{
let flag = false;
for(prop in item){
if(reg.test(prop)){
flag = true;
}
}
return flag;
});
}
Ответ 6
Один из способов - использовать Array#filter
, String#toLowerCase
и String#indexOf
как String#indexOf
ниже.
const arrayOfObject = [{
name: 'Paul',
country: 'Canada',
}, {
name: 'Lea',
country: 'Italy',
}, {
name: 'John',
country: 'Italy',
}];
function filterByValue(arrayOfObject, term) {
var ans = arrayOfObject.filter(function(v,i) {
if(v.name.toLowerCase().indexOf(term) >=0 || v.country.toLowerCase().indexOf(term) >=0) {
return true;
} else false;
});
console.log( ans);
}
filterByValue(arrayOfObject, 'ita');
Ответ 7
Вот как я буду делать это с помощью lodash:
const filterByValue = (coll, value) =>
_.filter(coll, _.flow(
_.values,
_.partialRight(_.some, _.method('match', new RegExp(value, 'i')))
));
filterByValue(arrayOfObject, 'lea');
filterByValue(arrayOfObject, 'ita');
Ответ 8
Этот код проверяет все вложенные значения до тех пор, пока не найдет то, что ищет, затем останавливается и возвращает true в "array.filter" для объекта, в котором он искал (если он ничего не может найти - возвращает false). Когда возвращается значение true, объект добавляется в массив, который возвращает метод array.filter.
const data = [{
a: "a",
b: {
c: "c",
d: {
e: "e",
f: [
"g",
{
i: "i",
j: {},
k: []
}
]
}
}
},
{
a: "a",
b: {
c: "c",
d: {
e: "e",
f: [
"g",
{
i: "findme",
j: {},
k: []
}
]
}
}
},
{
a: "a",
b: {
c: "c",
d: {
e: "e",
f: [
"g",
{
i: "i",
j: {},
k: []
}
]
}
}
}
];
function getState(data: any, inputValue: string, state = false) {
for (const value of Object.values(data)) {
if (typeof value === 'object' && value !== null && Object.keys(value).length > 0 && state === false) {
state = getState(value, inputValue, state);
} else {
if (state === false) {
state = JSON.stringify(value).toLowerCase().includes(inputValue.toLowerCase());
} else {
return state;
}
}
}
return state;
}
function filter(data: [], inputValue) {
return data.filter((element) => getState(element, inputValue));
}
console.log(filter(data, 'findme'));