オブジェクトの配列でvalue
を見つける必要があります--key
はactivity
です。ただし、activity
key
は深くすることができます次のように配列にネスト:
const activityItems = [
{
name: 'Sunday',
items: [
{
name: 'Gym',
activity: 'weights',
},
],
},
{
name: 'Monday',
items: [
{
name: 'Track',
activity: 'race',
},
{
name: 'Work',
activity: 'meeting',
},
{
name: 'Swim',
items: [
{
name: 'Beach',
activity: 'scuba diving',
},
{
name: 'Pool',
activity: 'back stroke',
},
],
},
],
},
{} ...
{} ...
];
そのため、特定のアクティビティーが配列内にあるかどうかを確認するための再帰アルゴリズムを作成しました。
let match = false;
const findMatchRecursion = (activity, activityItems) => {
for (let i = 0; i < activityItems.length; i += 1) {
if (activityItems[i].activity === activity) {
match = true;
break;
}
if (activityItems[i].items) {
findMatchRecursion(activity, activityItems[i].items);
}
}
return match;
};
ES6
このような配列にアクティビティが存在するかどうかを判断する方法は?
私はこのようなものを試しました:
const findMatch(activity, activityItems) {
let obj = activityItems.find(o => o.items.activity === activity);
return obj;
}
しかし、これは深くネストされたアクティビティでは機能しません。
ありがとう
some()
メソッドと再帰を使用して、アクティビティが任意のレベルに存在するかどうかを確認し、結果としてtrue/falseを返すことができます。
const activityItems = [{"name":"Sunday","items":[{"name":"Gym","activity":"weights"}]},{"name":"Monday","items":[{"name":"Track","activity":"race"},{"name":"Work","activity":"meeting"},{"name":"Swim","items":[{"name":"Beach","activity":"scuba diving"},{"name":"Pool","activity":"back stroke"}]}]}]
let findDeep = function(data, activity) {
return data.some(function(e) {
if(e.activity == activity) return true;
else if(e.items) return findDeep(e.items, activity)
})
}
console.log(findDeep(activityItems, 'scuba diving'))
再帰的なアルゴリズムほどエレガントではありませんが、配列をJSON.stringify()すると、次のようになります。
[{"name":"Sunday","items":[{"name":"Gym","activity":"weights"}]},{"name":"Monday","items":[{"name":"Track","activity":"race"},{"name":"Work","activity":"meeting"},{"name":"Swim","items":[{"name":"Beach","activity":"scuba diving"},{"name":"Pool","activity":"back stroke"}]}]}]
次に template literal を使用してパターンを検索できます。
`"activity":"${activity}"`
完全な機能:
findMatch = (activity, activityItems) =>
JSON.stringify(activityItems).includes(`"activity":"${activity}"`);
const activityItems = [{
name: 'Sunday',
items: [{
name: 'Gym',
activity: 'weights',
}, ],
},
{
name: 'Monday',
items: [{
name: 'Track',
activity: 'race',
},
{
name: 'Work',
activity: 'meeting',
},
{
name: 'Swim',
items: [{
name: 'Beach',
activity: 'scuba diving',
},
{
name: 'Pool',
activity: 'back stroke',
},
],
},
],
}
];
findMatch = (activity, activityItems) =>
JSON.stringify(activityItems).includes(`"activity":"${activity}"`);
console.log(findMatch('scuba diving', activityItems)); //true
console.log(findMatch('dumpster diving', activityItems)); //false
まず、再帰呼び出しで一致が見つかったら停止することにより、関数を改善できます。また、あなたは両方ともmatch
を外部で宣言し、それを返します。たぶん戻るだけのほうがいいでしょう。
const findMatchRecursion = (activity, activityItems) => {
for (let i = 0; i < activityItems.length; i += 1) {
if (activityItems[i].activity === activity) {
return true;
}
if (activityItems[i].items && findMatchRecursion(activity, activityItems[i].items) {
return true;
}
}
return false;
};
組み込みのディープ検索はありませんが、.find
必要に応じて、名前付き関数を使用します。
var result = !!activityItems.find(function fn(item) {
return item.activity === "Gym" || (item.items && item.items.find(fn));
});