javascriptの連想配列内で重複しているデータのみを抽出したいです。
この例では、'kind'が重複している配列のみ取り出したいのですが、連想配列で他行を参照して比較するという方法がわからずにいます。
filterや$.grepで実現できそうですが、具体的な方法を知りたいです。
const array = [ {'id': 1, 'category': 'animal', 'kind': 'dog'}, {'id': 2, 'category': 'fruit', 'kind': 'apple'}, {'id': 3, 'category': 'fruit', 'kind': 'orange'}, {'id': 4, 'category': 'animal', 'kind': 'dog'}, {'id': 5, 'category': 'animal', 'kind': 'cat'}, {'id': 6, 'category': 'fruit', 'kind': 'grape'}, ]
欲しい結果
[ {'id': 1, 'category': 'animal', 'kind': 'dog'}, {'id': 4, 'category': 'animal', 'kind': 'dog'} ]
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2019/09/06 03:47
回答3件
0
ベストアンサー
javascript
1const a= [ 2 {'id': 1, 'category': 'animal', 'kind': 'dog'}, 3 {'id': 2, 'category': 'fruit', 'kind': 'apple'}, 4 {'id': 3, 'category': 'fruit', 'kind': 'orange'}, 5 {'id': 4, 'category': 'animal', 'kind': 'dog'}, 6 {'id': 5, 'category': 'animal', 'kind': 'cat'}, 7 {'id': 6, 'category': 'fruit', 'kind': 'grape'}, 8] 9var b=a.filter((x,y,z)=>z.slice(0,z.length).filter(w=>w.kind==x.kind).length>=2); 10console.log(b);
投稿2019/09/06 04:13
総合スコア116661
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2019/09/06 05:02
0
楽かどうか良いかどうかはわかりませんが単純に「jQuery 連想配列 比較」で検索したところ以下のようなサイトのコードが使えそうです。
JavaScriptでのObject比較方法
JavaScript
1function objectEquals(a, b){ 2 3 if(a === b){ 4 // 同一インスタンスならtrueを返す 5 return true; 6 } 7 8 // 比較対象双方のキー配列を取得する(順番保証のためソートをかける) 9 var aKeys = Object.keys(a).sort(); 10 var bKeys = Object.keys(b).sort(); 11 12 // 比較対象同士のキー配列を比較する 13 if(aKeys.toString() !== bKeys.toString()){ 14 // キーが違う場合はfalse 15 return false; 16 } 17 18 // 値をすべて調べる。 19 var wrongIndex = aKeys.findIndex(function(value){ 20 // 注意!これは等価演算子で正常に比較できるもののみを対象としています。 21 // つまり、ネストされたObjectやArrayなどには対応していないことに注意してください。 22 return a[value] !== b[value]; 23 }); 24 25 // 合致しないvalueがなければ、trueを返す。 26 return wrongIndex === -1; 27} 28 29var a = {"a":"a","b":"b"}; 30var b = {"b":"b","a":"a"}; 31 32console.log(objectEquals(a, b)); // -> true 33 34var c = {"a":"a","b":"c"}; 35var d = {"a":"a","b":"b"}; 36 37console.log(objectEquals(c, d)); // -> false
投稿2019/09/06 03:44
編集2019/09/06 03:46総合スコア10429
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
こんにちは
例えば、以下でいかがでしょう?
まず、
javascript
1const groupingMap = array.reduce( 2 (map, e) => map.set(e.kind, [ ...(map.get(e.kind) || []), e] ), new Map())
で、 kind
の値をキーとし、その値のkind
を持つ要素の配列を値とするマップを作ります。次に
javascript
1const duplicatedElements = [...groupingMap].filter(([kind, array]) => array.length > 1 )
で、マップのエントリを配列にして、その中で、該当要素の配列の長さが1より大きいものだけを抽出します。
上記に対して、元の array
が以下
javascript
1const array = [ 2 {'id': 1, 'category': 'animal', 'kind': 'dog'}, 3 {'id': 2, 'category': 'fruit', 'kind': 'apple'}, 4 {'id': 3, 'category': 'fruit', 'kind': 'orange'}, 5 {'id': 4, 'category': 'animal', 'kind': 'dog'}, 6 {'id': 5, 'category': 'animal', 'kind': 'cat'}, 7 {'id': 6, 'category': 'fruit', 'kind': 'grape'}, 8 {'id': 7, 'category': 'animal', 'kind': 'cat'} 9]
であったとき(※最後の id: 7 の要素を追加しています。)、 duplicatedElements
の内容を
javascript
1duplicatedElements.forEach(([kind, array]) => { 2 console.log(`${kind}:`) 3 array.forEach(e => { 4 console.log(` ${JSON.stringify(e)}`) 5 }) 6})
にて、表示すると以下になります。
dog: {'id':1,'category':'animal','kind':'dog'} {'id':4,'category':'animal','kind':'dog'} cat: {'id':5,'category':'animal','kind':'cat'} {'id':7,'category':'animal','kind':'cat'}
- 動作確認用 CodePen: https://codepen.io/jun68ykt/pen/gOYoGda
追記
配列やオブジェクトの操作で便利なメソッドを提供している、Lodash の _.groupBy を使うと、上記のコードで groupingMap
相当のオブジェクトを作ってくれるので、以下のようにも書けます。
javascript
1const groupingObject = _.groupBy(array, e => e.kind) 2 3const duplicatedElements = Object.entries(groupingObject).filter(([kind, ary]) => ary.length > 1)
- 動作確認用 CodePen: https://codepen.io/jun68ykt/pen/oNvpGJR
追記2
上記に挙げた2つのコードのように、いったんkind
の値をキーとして、同じ kind
の要素を集めるという処理を経なくても、 array
の要素のうち、kind
の同じものが他にもある要素だけを残す処理は、(やや無駄もありますが。)以下のように書けます。
javascript
1const duplicatedElements = array.filter( 2 (e, i) => array.find((e2, j) => e.kind === e2.kind && i !== j) 3)
ただし、これだと
javascript
1const array = [ 2 {'id': 1, 'category': 'animal', 'kind': 'dog'}, 3 {'id': 2, 'category': 'fruit', 'kind': 'apple'}, 4 {'id': 3, 'category': 'fruit', 'kind': 'orange'}, 5 {'id': 4, 'category': 'animal', 'kind': 'dog'}, 6 {'id': 5, 'category': 'animal', 'kind': 'cat'}, 7 {'id': 6, 'category': 'fruit', 'kind': 'grape'}, 8 {'id': 7, 'category': 'animal', 'kind': 'cat'}, 9 {'id': 8, 'category': 'fruit', 'kind': 'melon'}, 10 {'id': 9, 'category': 'fruit', 'kind': 'grape'} 11]
のときに、結果として得られる配列が
[ {'id':1,'category':'animal','kind':'dog'}, {'id':4,'category':'animal','kind':'dog'}, {'id':5,'category':'animal','kind':'cat'}, {'id':6,'category':'fruit','kind':'grape'}, {'id':7,'category':'animal','kind':'cat'}, {'id':9,'category':'fruit','kind':'grape'} ]
というものになり、 kind
の同じ要素が必ずしも隣接しないです。
- 動作確認用 CodePen: https://codepen.io/jun68ykt/pen/bGbaYVR
投稿2019/09/06 03:53
編集2019/09/06 04:47総合スコア9058
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。