状況説明がちょっと足りてなくて、半分程度しか理解出来てませんが
js
1x.room1 === "102" || x.room2 === "102" || x.room3 === "102"
この関数が可変になる、いい感じの関数を流し込みたいということでしょうか?
使い勝手の良い関数さえ準備できれば、keys.filter(fn)
というコード一撃で解決出来ますからね。
2段階で引数要求するようにすれば使い回せる関数を準備出来ます。
js
1const keys = [
2 {"keyno":"A1","room1":"102","room2":"103"},
3 {"keyno":"B2","room1":"201","room2":"202"},
4];
5const isValidKey = (rooms, roomNo, key) =>
6 rooms.map(it => key[it]).some(it => it === roomNo);
7const output = it => console.log(it);
8
9keys
10 .filter(isValidKey.bind(null, ['room1', 'room2'], "102"))
11 .forEach(output);
12// {keyno: "A1", room1: "102", room2: "103"}
今回はFn.bindを利用して引数を束縛するという事を行いました
これを部分適用と呼び、これにはいくつかパターンがあります。
こんな風に実行する度に引数を束縛し、引数が3つ揃った瞬間に発火する仕組みを作る事も可能です。
js
1const isValidKey = rooms => roomNo => key =>
2 rooms.map(it => key[it]).some(it => it === roomNo);
3
4// 使い方はこのように変化する
5keys
6 .filter(isValidKey(['room1', 'room2'])("102"))
7 .forEach(output);
8// {keyno: "A1", room1: "102", room2: "103"}
最後にroomの名称が可変なのでその場その場で書き換えたくないというなら、
それなりの配列を定義しておきましょうという話になります。
一応鍵の配列から作れそうだったのでそちらも作って終わりにします。
鍵が用意出来るなら一覧も作れるでしょうからね。
js
1// 質問文から弄って、A1の鍵はroom3を、A2の鍵はroom4の情報をもたせている
2const keys = [
3 {"keyno":"A1","room1":"101","room2":"102","room3":"103"},
4 {"keyno":"B2","room1":"201","room2":"202","room4":"203"},
5];
6const rooms = keys
7 .map(it => Object.keys(it).filter(it => it !== "keyno"))
8 .reduce((arr, it) => [
9 ...arr,
10 ...it.filter(key => !arr.includes(key))
11 ]);
12
13console.log(rooms);
14// ["room1", "room2", "room3", "room4"]
15// 重複してないしroom3もroom4も含んでいる配列になった
【おまけ】 データ構造変更の提案
js
1[
2 {"keyno":"A1","room1":"102","room2":"103"},
3 {"keyno":"B2","room1":"201","room2":"202"},
4];
冒頭に存在するコレ、非常に扱いにくいです。
room1とかroom2とか誰が決めたんですか?
1番目ルームなのに102号室だったり、201号室だったりして一貫性がありません。
普通に考えてこうなっているべきです。
A1の鍵で開けられるのは102号室・103号室の2つですよという意味がバシッと通って使いやすくなっています。
js
1[
2 {keyno:"A1", rooms: ["102", "103"]},
3 {keyno:"B2", rooms: ["201", "202"]},
4]
5 .filter(key => key.rooms.includes("102"))
6 .forEach(it => console.log(it));
7// {keyno: "A1", rooms: ["102", "103"]}
どうしても変更出来ないというのであれば、
こういう風にメインロジックに持ち込みやすい形に整形すると良いでしょう。
js
1const keys = [
2 {"keyno":"A1","room1":"102","room2":"103"},
3 {"keyno":"B2","room1":"201","room2":"202"},
4].map(key => ({
5 keyno: key.keyno,
6 rooms: Object.keys(key).filter(it => it !== "keyno").map(it => key[it]),
7}));
8console.log(keys);
9// [{keyno: "A1", rooms: ["102", "103"]}, {keyno: "B2", rooms: ["201", "202"]}]
10
11keys
12 .filter(key => key.rooms.includes("102"))
13 .forEach(it => console.log(it));
14// {keyno: "A1", rooms: Array(2)}