はじめに
コジマです。
以下のようなデータを考えます。
ユーザーとそのユーザーの持ち物があります。(weightは適当につけました)
これが全ユーザー合わせて何種類あるのか考えたいです。
const users = [ {name: '織田', items: [ {name: '消しゴム', weight: 10}, {name: 'シャーペン', weight: 20}, {name: '筆箱', weight: 30}, {name: '鞄', weight: 40} ]}, {name: '豊臣', items: [ {name: '手鏡', weight: 10}, {name: '靴', weight: 20}, {name: '帽子', weight: 30} ]}, {name: '徳川', items: [ {name: '消しゴム', weight: 10}, {name: '手鏡', weight: 20}, {name: 'アンパン', weight: 30}, {name: '牛乳', weight: 40} ]} ]
数えると合計11個のアイテムの中で2個重複があるので、9種類になります。
愚直なやり方
べたなやり方としては、なにかしらの配列を用意しておいて、
その配列に含まれてなければpushする。みたいな処理を入れてその長さを取る方法かと思います。
const itemNames = []; for(const user of users){ for(const item of user.items){ if(itemNames.indexOf(item.name) === -1){ itemNames.push(item.name); } } } console.log(itemNames.length); // 9
2重ループしてif文入れるので、ネストも深くなるし、O(n^2)の計算量をこのためだけに
使うのはなかなかしんどいですね。
ワンライナーで片づける
正直、可読性という面では欠けると思いますが、スマートになります。
const itemNames = Array.from(new Set(users.map(e1 => e1.items.map(e2 => e2.name)).reduce((acc, val) => { return acc.concat(val) }, []))); console.log(itemNames.length);
いくつかのテクニックを合わせています。
(1)reduceとconcatを使った平坦化
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
(2)mapを使った配列の作成
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map
(3)Array.fromとSetを使った配列の重複削除
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/from
アイテム名だけの配列を作る=>平坦化する=>重複を削除する
という流れですね。
さいごに
ちょっと変なことやりたいときも既存の知識の組み合わせで実現できます。
こんなことをやらなくちゃいけないことがあったのでまとめてみました。
何事も基本が大事ですね。
この記事を面白いまたは役に立ったと思ってくれた方は是非私のTwitter(@kojimanotech)を
フォローしてくれたらうれしいです!
もっと学びたい人はこちら
JavaScriptをもっと学びたいエンジニアのためにおすすめのUdemy講座を紹介いたします!
JavaScript初心者向けの講座です。
HTML、CSSと合わせて学ぶことができます。
フロントエンド開発の基本的な知識を網羅的に学ぶことができます。
個人的には著作権表記についても触れているところが推せますね。
ウェブ開発入門完全攻略コース – HTML/CSS/JavaScript. プログラミングをはじめて学び創れる人へ!
JavaScriptをより深く学びたい人はこちらがおすすめです。
JavaScript初心者を脱するとよりよいコードを書かなければなりません。
つまずきがちなオブジェクト操作や、非同期処理の仕組みについて学ぶこともできるため、JavaScriptの仕組みから深く学ぶことができます。
【JS】ガチで学びたい人のためのJavaScriptメカニズム
気になった人はぜひ見てみてくださいね!
以上、コジマでした。