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

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

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

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

Q&A

解決済

4回答

1652閲覧

配列に重複がある場合の整理方法

pegy

総合スコア245

JavaScript

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

0グッド

0クリップ

投稿2020/08/05 06:09

var aryOriginal = [["a",100],["b",200],["a",300]]

例えば上記のような配列が存在した場合結果的にaが2つ存在するので

var aryResult = [["a",400],["b",200]]
のように重複を整理したいと考えております。

Javascript

1for (var i = 0; i < 3, i++) { 2 //0 3 if(aryOriginal[i][0]==aryOriginal[i+1][0]){ 4 //加算していく 5 } 6if(aryOriginal[i][0]==aryOriginal[i+2][0]){ 7 //加算していく 8 } 9 //1 10  if(aryOriginal[i][0]==aryOriginal[i-1][0]){ 11 //加算していく 12 } 13   if(aryOriginal[i][0]==aryOriginal[i+1][0]){ 14 //加算していく 15 } 16//以下省略 17} 18コード

上記のように総当たりでループして一致すれば等も思いつくのですが、明らかにスマートな方法ではないのが自分で思います。良いアイデアが思いつかずスマートなメソッドや考え方などがあればアドバイスを頂きたく存じます。

宜しくお願い申し上げます。

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

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

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

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

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

guest

回答4

0

ベストアンサー

一旦配列を連想配列形式にして、最後に配列形式にする、とかでどうでしょうか?

js

1 2var aryOriginal = [["a",100],["b",200],["a",300]], 3 map = {}, 4 result = []; 5 6aryOriginal.map(function(v) { 7 8 if (map[v[0]]) { 9 // 同じキーがあれば合算する 10 map[v[0]] = map[v[0]] + v[1]; 11 } else { 12 map[v[0]] = v[1]; 13 } 14 15}); 16 17console.log(map) 18// Object { a: 400, b: 200 } 19 20result = Object.keys(map).map(function (key) { 21 return [key, parseInt(map[key])] 22}) 23 24console.log(result) 25// Array [Array ["a", 400], Array ["b", 200]] 26

投稿2020/08/05 06:50

HarukaKanamaru

総合スコア37

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

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

pegy

2020/08/05 07:22

ありがとうございます。ご教示いただいた内容で解決することができました! 私的にシンプルであったため、ベストアンサーにさせてください。
guest

0

入力が配列であり、配列要素の値を評価する限り総当たりは必須でしょう。

Map の派生として抽象化する例

javascript

1// 抽象化 2class MyMap extends Map { 3 constructor() { 4 super(); 5 } 6 appendTest( key, val ) { 7 if( this.has( key ) ) { 8 this.set( key, this.get(key) + val ); 9 } 10 else { 11 this.set( key,val ); 12 } 13 } 14 static fromPairs( a ){ 15 let m = new MyMap(); 16 a.forEach( ([k,v]) =>m.appendTest(k,v) ); 17 return m; 18 } 19} 20 21// 活用 22var aryOriginal = [["a",100],["b",200],["a",300]]; 23var dstAry = MyMap.fromPairs(aryOriginal).entries(); 24console.log( [...dstAry] ); // [["a",400],["b",200]] 25

追記)

Array#reduceを使う例:

javascript

1var src = [["a",100],["b",200],["a",300]]; 2var dst = Object.entries(src.reduce((o,[k,v])=>(o.hasOwnProperty(k)?o[k]+=v:o[k]=v,o),{})); 3/* 4var dst = Object.entries(src.reduce((o,[k,v])=> { 5 o.hasOwnProperty(k) 6 ? o[k]+=v 7 : o[k]=v; 8 return o},{})); 9*/ 10console.log( dst );

処理内容は他の回答と同様です。

  1. オブジェクトを連想配列のように扱う(initialValueに {} を与えて重複のない key-value を作る)。

Object#hasOwnProperty() を使うのは、初めて処理するペアの値に0があると falsyとなるため。
2. Object.entries() で配列化する。

投稿2020/08/05 06:32

編集2020/08/05 07:14
AkitoshiManabe

総合スコア5434

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

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

pegy

2020/08/05 07:23

ありがとうございます。教えていただいた内容で実装することを確認することができました。
guest

0

HarukaKanamaruさんのコードが短くてすっきりしていて素敵だと思いました。

自分も自作のライブラリ使って解いてみたので一応回答します。

別の回答のときに、groupという関数を作りました。
JavaScript - 二次元配列をグループ分けしてキー名をつけてオブジェクトに変換する方法|teratail

それをライブラリに組み込みました。
https://www.npmjs.com/package/@standard-software/parts

Try on RunKit というのを使って動かしてみました。

js

1var parts = require("@standard-software/parts") 2 3const arrayOriginal = [["a",100],["b",200],["a",300]] 4const result = parts.array.group(arrayOriginal, v => v[0], true); 5// 配列0番目でグループ化する 6 7// console.log(result); 8const arrayResult = []; 9result.index.forEach((v, i) => { 10 // グループ化したものに対して内部値をSumして新たな値を作る 11 arrayResult.push([v, parts.array.sum(result.result[i].map(v => v[1]))]) 12}) 13 14console.log(arrayResult); 15//[["a", 400], ["b", 200]]

動作確認は、このURLでできます。
https://runkit.com/embed/2q4m92pezlhm

投稿2020/08/05 07:28

standard-soft

総合スコア197

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

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

0

こんな感じでどうでしょうか?

const arr = [["a",100],["b",200],["a",300]] const res = {} arr.forEach(v => { const [key, val] = v if (!res[key]) { res[key] = 0 } res[key] += val }) const uniques = Object.entries(res) console.log(uniques) // [ [ 'a', 400 ], [ 'b', 200 ] ]

投稿2020/08/05 06:39

anozon

総合スコア662

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

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

pegy

2020/08/05 07:23

ありがとうございます。ご教示いただいた内容でも動作させることと、理解することができました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問