Lodashのチェイン記法を使えば一撃です。
上記のQiitaの記事では_(val)
スタートの場合はプリミティブ値かLodashオブジェクトか戻り値か分からないみたいな事が書いてありますが、
このメソッドはどちらを返すかはドキュメントに明記されています。
面倒ならば_.chain(val)
始動で統一すれば良いです。
js
1const obj = {
2 one:{
3 two:{
4 smith:{ a:true, b:false },
5 john :{ a:true, b:true, c:true },
6 },
7 },
8};
9const trues = _.chain(obj.one.two)
10 .toPairs()
11 .filter(([key, val]) => Object.values(val).includes(true))
12 .map(([key]) => key)
13 .value();
14
15result = trues;
Online Lodash Testerはresult変数に値を突っ込んだら結果を返してくれる仕組みなので結果をresult変数に突っ込んで…
はい
ユニークなものだけ抽出したいんですっけ?
基本的にオブジェクトはキーが重複する事はありえないので、one, twoがそれぞれ複数キーを所持しており、
それらをマージして重複キーが出来たと仮定しましょう。
js
1const result1 = ["smith", "john"];
2const result2 = [...result1, ...result1];
3
4console.log(result2);
5// ["smith", "john", "smith", "john"]
6
7result = _.uniq(result2);
8// ["smith", "john"]
【おまけ】 ネイティブのJSだけでやる
イディオムが増えるのでLodashに比べるとかなり可読性が落ちます。
one配下にtwoとthreeのキーが存在しており、
重複キーを取り除きつつ結果を作る想定でやっています。
js
1const obj = {
2 one:{
3 two:{
4 smith:{ a:true, b:false },
5 john :{ a:true, b:true, c:true },
6 },
7 three:{
8 smith:{ a:true, b:false },
9 will :{ a:true, b:true, c:true },
10 }
11 },
12};
13const result = Object.values(obj.one)
14 .map(its => Object
15 .entries(its)
16 .filter(([key, val]) =>
17 Object.values(val).includes(true)
18 )
19 .map(([key]) => key)
20 )
21 .reduce((arr, it) => [...arr, ...it])
22 .reduce((arr, it) => {
23 if (!arr.includes(it)) arr.push(it);
24 return arr;
25 }, []);
26
27console.log(result);
28// ["smith", "john", "will"]
.reduce((arr, it) => [...arr, ...it])
2次元配列を1次元配列にするイディオム
.reduce(arr, it) => {if (!arr.includes(it)) arr.push(it);...
1次元配列からユニークなものだけ取り出すイディオム
(個人的にfilterの方法は好きではないだけ)