Posted at

Objectをループさせて条件判定するときはarrayに変換してsome()とevery()を使うと便利


概要

jsのObjectではarrayの便利な関数が使えません。

なので、一度Object.keys()を使ってキーのarrayを取得してあげる必要があります。

その後メソッドチェーンしてあげればarrayのメソッドがそのまま使えます。


オブジェクトの中のキーが有効なものであるか確認して処理を分岐したい

今回は一つでもvalueが空ではないプロパティがあればデータを有効とみなすのでarray.some()を使ってみましょう。

MDN公式ドキュメント

array.some()とは…


some() メソッドは、配列の少なくとも 1 つの要素が、渡された関数によって実施されるテストに通るかどうかをテストします。


↑の通り、1つでも有効なキーがあれば結果としてtrueを返すということですね。


サンプルコード

function isArrayActive(obj) {

return Object.keys(obj).some(function (key) {
return obj[key] ? true : false;
});
}

// 無効ユーザ
const user = {
name: "",
type: "",
flag: false,
data: null
};

// 有効ユーザ
const user2 = {
name: "Tanaka",
type: "",
flag: false,
data: null
};

if(isArrayActive(user)) {
console.log("active");
} else {
console.log("not active");
}

if(isArrayActive(user2)) {
console.log("active");
} else {
console.log("not active");
}

// not active
// active

このサンプルコードの場合、オブジェクトのプロパティに1つでも有効なものがあればtrueと判定されます。nametypeが有効でuploadがtrueのデータのオブジェクト…とか判定しようとする時はsomeは使えないですね…

オブジェクトのプロパティに対して複数条件指定して有効であるか調べるなら、everyを使うのが良さそうです。

MDN公式ドキュメント


every() メソッドは、与えられた関数によって実行されるテストに、配列のすべての要素が通るかどうかをテストします。


function isUserActive(user) {

const isActive = {
name : user.name ? true : false,
type : user.type === "human" ? true : false,
upload : user.upload ? true : false
};
// Objectの要素全てがtrueであればtrue、ひとつでもfalseがあればfalse
return Object.keys(isActive).every(function (type){
return isActive[type];
});
}

const user = {
name : "",
type : "",
upload : false,
data : null
};

const user2 = {
name : "Tanaka",
type : "human",
upload : true,
data : null
};

console.log(isUserActive(user));
console.log(isUserActive(user2));

// false
// true

こんな感じでしょうか。

また、return部分ですが

if(isActive.name && isActive.type && isActive.upload) {

return true;
}

みたいな感じでもうまくいきますが、条件が増えたときこちらの条件式に手を加えなきゃいけなくなるので2度手間になります。arrayのテストメソッドを上手く使ってスリムに書くといい感じなのでおすすめです。