我想知道根据字符串关键字过滤对象数组的最干净、更好的方法是什么。必须在对象的任何属性中进行搜索。
当我输入
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'}]
您可以对其进行过滤并仅搜索搜索字符串的一次出现。
使用方法:
Array#filter
,只是为了用条件过滤数组,Object.keys
用于获取对象的所有属性名称,Array#some
用于迭代键并退出循环(如果找到),String#toLowerCase
以获得可比较的值,String#includes
用于检查两个字符串,如果一个包含另一个。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; }
当我们已经知道它不会是用方法搜索对象时,我们可以执行以下操作来节省时间复杂度:
function filterByValue(array, value) {
return array.filter((data) => JSON.stringify(data).toLowerCase().indexOf(value.toLowerCase()) !== -1);
}
使用Object.keys循环遍历对象的属性。使用reduce和filter让代码更加高效:
const results = arrayOfObject.filter((obj)=>{
return Object.keys(obj).reduce((acc, curr)=>{
return acc || obj[curr].toLowerCase().includes(term);
}, false);
});
其中 term 是您的搜索词。
您始终可以使用
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);
一种方法是使用
Array#filter
、String#toLowerCase
和 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');
这是上述版本的一个版本,它按从对象属性数组派生的值进行过滤。该函数接受对象数组和指定的对象属性键数组。
// fake ads list with id and img properties
const ads = [{
adImg: 'https://test.com/test.png',
adId: '1'
}, {
adImg: 'https://test.com/test.png',
adId: '2'
}, {
adImg: 'https://test.com/test.png',
adId: '3'
}, {
adImg: 'https://test.com/test-2.png',
adId: '4'
}, {
adImg: 'https://test.com/test-2.png',
adId: '5'
}, {
adImg: 'https://test.com/test-3.png',
adId: '6'
}, {
adImg: 'https://test.com/test.png',
adId: '7'
}, {
adImg: 'https://test.com/test-6.png',
adId: '1'
}];
// function takes arr of objects and object property
// convert arr of objects to arr of filter prop values
const filterUniqueItemsByProp = (arrOfObjects, objPropFilter) => {
return arrOfObjects.filter((item, i, arr) => {
return arr.map(prop => prop[objPropFilter]).indexOf(item[objPropFilter]) === i;
});
};
const filteredUniqueItemsByProp = filterUniqueItemsByProp(ads, 'adImg');
console.log(filteredUniqueItemsByProp);
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;
});
}
这是我使用 lodash 的方法:
const filterByValue = (coll, value) =>
_.filter(coll, _.flow(
_.values,
_.partialRight(_.some, _.method('match', new RegExp(value, 'i')))
));
filterByValue(arrayOfObject, 'lea');
filterByValue(arrayOfObject, 'ita');
对于那些有兴趣使用
for
循环解决方案的人。
array[index]
typeof array[index][key] === 'string'
和array[index][key]
是否包含搜索键 -> 将array[index]
存储到filtered
数组。function filterByValue(array, string) {
let filtered = Array();
for(let i = 0; i < array.length; i++) {
const keys = Object.keys(array[i]);
for(let j = 0; j < keys.length; j++) {
const value = array[i][keys[j]];
if(typeof value === 'string' &&
value.toLowerCase().includes(string.toLowerCase())) {
filtered.push(array[i]);
break;
} else {
continue;
}
}
}
return filtered;
}
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'}]