質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

3回答

1277閲覧

オブジェクト配列で重複を除外したい

hokosugi

総合スコア63

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/08/21 04:09

連想配列で重複を避けながら整形したいです。以下のようなoriginalArrを
0. key2を重複をなくして配列にし
0. key1も重複をなくす配列に
0. key2をkeyにvalueを 2.のkey1にする

そして下記のようなコードを作成して、一応動かせます。
ただ、もっと簡単にメソッドなんか使ってシンプルに書きたいです。
コード改善をお願いします。

javascript

1const originalArr = [ 2 { 3 "key1":"shiba", 4 "key2":"dog"}, 5 { 6 "key1":"shiba", 7 "key2":"dog"}, 8 { 9 "key1":"akita", 10 "key2":"dog"}, 11 { 12 "key1":"mike", 13 "key2":"cat"}, 14 { 15 "key1":"mike", 16 "key2":"cat"} 17]; 18const reduceArr = []; 19//reduceでなくてもいいかも? 20const reduce = originalArr.reduce(function(result, current){ 21 return reduceArr.push(current.key2); 22},0); 23const reduceObj = new Set(reduceArr); // 重複排除 24const uniqueArr = Array.from(reduceObj); // obj=>arr 25const doneArr = []; //実行後の配列 26let key2; 27for(let i=0; i<uniqueArr.length; i++){ 28 const finalArrBefore = []; 29 originalArr.forEach(el=>{ 30 const key1 = el['key1']; // inu or neko 31 const elKey2 = el["key2"]; // dog or cat 32 key2 = uniqueArr[i]; //[dog, cat] 33 if (elKey2==key2){ 34 finalArrBefore.push(key1) 35 } 36 }) 37 const finalObj = new Set(finalArrBefore); //重複排除 38 const finalArr = Array.from(finalObj); // obj=>arr 39 const obj = { 40 key2: key2, 41 key1: finalArr 42 }; 43 doneArr.push(obj); 44} 45console.log(doneArr); 46/* 47[ 48 { key2: 'dog', key1: [ 'shiba', 'akita' ] }, 49 { key2: 'cat', key1: [ 'mike' ] } 50] 51*/

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

むずかしいのはわかんないので

javascript

1const originalArr = [ 2 { 3 "key1":"shiba", 4 "key2":"dog"}, 5 { 6 "key1":"shiba", 7 "key2":"dog"}, 8 { 9 "key1":"akita", 10 "key2":"dog"}, 11 { 12 "key1":"mike", 13 "key2":"cat"}, 14 { 15 "key1":"mike", 16 "key2":"cat"} 17]; 18let animal = {}; 19for (let obj of originalArr) { 20 const k = obj.key2; 21 const v = obj.key1; 22 if (!animal[k]) animal[k] = []; 23 if (!animal[k].includes(v)) animal[k].push(v); 24} 25let doneArr = []; 26for (let key in animal) { 27 doneArr.push({"key2":key,"key1":animal[key]}); 28} 29console.log(doneArr);

投稿2021/08/21 12:06

takasima20

総合スコア7460

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hokosugi

2021/08/21 12:27

ご回答ありがとうございます。これは簡単でシンプルですね。全く思いつかなかったので、なるほどなあっと感心しきりです。if (!animal[k].includes(v)) animal[k].push(v);このあたり、自分なら総当りしてしまいそうw いや間違いなくそうしてるww 改めてありがとうございました。
guest

0

面白そうなので組んでみた。

JavaScript

1const res = Array.from( originalArr.reduce( ( pre,cur )=> { 2 return pre.set( cur.key2, ( pre.get( cur.key2 ) || new Set() ).add( cur.key1 ) ); 3}, new Map() ) ).map( mp=> { 4 return { key2: mp[ 0 ], key1: [ ...mp[ 1 ] ] }; 5} ); 6console.dir( res ); 7```**動くサンプル:**[https://jsfiddle.net/vnr2maek/1/](https://jsfiddle.net/vnr2maek/1/) 8 9【Array.prototype.reduce() - JavaScript | MDN10[https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) 11 12Map - JavaScript | MDN13[https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Map](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Map) 14 15【Set.prototype.add() - JavaScript | MDN16[https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set/add](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set/add)

投稿2021/08/21 06:27

kei344

総合スコア69458

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hokosugi

2021/08/21 08:55

ご回答ありがとうございます。ちょっとすぐには理解できませんww 今から熟読して理解したいと思います。
kei344

2021/08/21 09:20

調子に乗って圧縮しすぎました、すみません。 reduceの第二引数にMapオブジェクトを渡して、pre.setでcur.key2をキーにSetオブジェクトをvalueに設定しています。Array.from().map()はその結果のMapオブジェクトを配列化して最終出力の形に整形しています。 ちょっと展開しました⇒ https://jsfiddle.net/bcg2wqo7/ 【reduce()はArrayにて最強……おぼえておけ。(配列とかおれおれAdvent Calendar2018 – 23日目) | Ginpen.comhttps://ginpen.com/2018/12/23/array-reduce/
hokosugi

2021/08/21 12:08

ありがとうございます。ようやく理解できました。Setの特性生かしてreduce構文の中で重複を外しているんですね。一行ずつにconsole.log, consoloe.dir入れてやっとこさですw 展開してもらわないと明日の朝まで掛かったかも知れませんw 助かりました!
guest

0

自分、便利なものは使いまくって楽したい派なもんで、こないな感じでやりますわー

javascript

1const key2s = _(originalArr) 2 .map('key2') 3 .uniq() 4 .value(); 5 6const map = _(originalArr) 7 .groupBy('key2') 8 .mapValues( 9 ary => _(ary).map('key1').uniq().value() 10 ) 11 .value(); 12 13 14const doneArr = key2s.map(key2 => ({ key2, key1: map[key2] }));

サンプル

**補足: **最終結果のdoneArrに含まれるkey2の順番が、もとのoriginalArrでのkey2の出現順を必ずしも保存していなくてもええんやったら、key2s を作っておく必要はないねんな。 上のコードに出てくる変数map を Object.entries() だったり、lodashの toPairsで配列にバラしたらええんやからの。

サンプルその2

**補足2: **それと、こまいこともうひとつ言うとくわ。質問にあるコードでは、originalArrの要素の並び順は、key2 の値で(dogの次にcat やから降順に)ソートされている風に見えるんやけど、前提として、そうやってkey2の順にもともとキレイに並んでるゆうんやったら、また別のやりようあるやもしれん。ワテのコードは、そないな前提なしで、originalArrの中では各要素は何の順にもなっとらんでもええものになっとるで。

補足3:
以下の3条件を満たすコード書いてみたで ➡サンプルその3

・ lodash を使わない。
・ 検索を効率化するための補助のオブジェクトやMap、Setを使わない。(先頭から探すことで、とりあえずOKとする)
・ doneArrの中で、key1 や key2 の出現順は、元の originalArr での出現順を保存している。

投稿2021/08/21 05:33

編集2021/08/22 07:57
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hokosugi

2021/08/21 08:54

ありがとうございます! lodash、初めて知りましたw これを使うならどんなことでも簡単に楽して整形できそうです。key2の出現順は全く考えずに適当にサンプル配列を作っております。そういうところまで考えないといけないほどスキル上がれば嬉しいですが。今回は有難うございました。
退会済みユーザー

退会済みユーザー

2021/08/22 03:43

おおきに〜。lodash 便利やでえ。今回の問題であれば、(1) 何らかのキーによるグループ化 (2) 配列の要素をユニークにする、ゆう二つのテーマがあり、さらにもうひとつ検討事項として (3) 元の配列における出現順を加工後も保存するのかどうか? というのがありますな。これらのどれも、何作ってるときでも、よう出てきまっせ。そやからこれらをまずlodash使わず、reduceだったり map 、 filter とか、その他モロモロの標準のメソッドと、中間の加工物としてMapやSet やなんかを使うコードをサラっと書けるようになっときいや。ほんで、その後、lodashの便利メソッドを見るとやな、「ははあ、、、これは中ではこないなことやってんのやろな・・・」と推測がつくようになる。(興味があればlodashのソースコードを読んでもええし。)そうやって、自分で書こうと思えば書けるやつから頭に入って、実践で「あ。コレlodashのアレ使えば一発やん」みたいに思いつくようになるし、メソッドと標準メソッドの合わせ技とかもスラスラいけるようになるで。
hokosugi

2021/08/22 22:02

ありがとうございます!!頑張ります!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問