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つの出現のみを検索できます。
使用される方法:
Array#filter
、条件で配列をフィルタリングするためだけに、
Object.keys
オブジェクトのすべてのプロパティ名を取得するため、
Array#some
キーを反復し、見つかった場合はループを終了します。
String#toLowerCase
比較可能な値を取得するため、
String#includes
2つの文字列をチェックする場合、一方が他方を含む場合。
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」にtrueを返します(何も見つからない場合を除き、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'));
複数のキーワードを含むオブジェクトを検索する必要がある場合は、フィルターに掛けられたオブジェクトをさらに絞り込み、フィルターをさらに使いやすくします。
const data = [{
a: "a",
b: {
c: "c",
d: {
e: "findme2",
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: "findme2",
f: [
"g",
{
i: "findme",
j: {},
k: []
}
]
}
}
}
];
function filter(data: [], inputValue: string) {
return data.filter((element) => checkState(element, inputValue));
}
function checkState(element: any, inputValue: string) {
const filterValues = inputValue.trim().split(' ');
const states: boolean[] = [];
for (let index = 0; index < filterValues.length; index++) {
states[index] = getState(element, filterValues[index]);
}
return states.every(state => state === true);
}
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;
}
console.log(filter(data, 'findme')); // gets all objects that contain "findme"
console.log(filter(data, 'findme findme2')); // gets all objects that contain "findme" and "findme2"
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');
1つの方法は、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');