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

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

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

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

Q&A

解決済

5回答

4396閲覧

2次元配列を特定の要素でグルーピングし、3次元配列に組み直す

true

総合スコア440

JavaScript

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

0グッド

1クリップ

投稿2015/11/27 05:18

いま、下記コードに示すような2次元配列aryがあり、ary2はaryについて関東、東海、北陸でグルーピングしたときの各グループの個数を示しています。これらはGASのスプレッドシート上からQUERY関数等を駆使して2次元配列を取得しており、通常のSQL段階での加工は諦め、JavaScript上でこの作業をやるハメになっているという前提です。

強引かもしれませんが、下記コードで実現しました。が、どうも無駄が多いような気がするので別解があればよろしくお願い致します。たとえばary2って不要な気もしますし。いつも要領の悪いコードで恐縮です。

var ary = []; var ary2 = []; var ary3 = []; var ary4 = []; var k = 0; ary = [["関東", "東京"],["関東","神奈川"],["関東","千葉"],["関東","埼玉"],["東海","愛知"],["東海","三重"],["東海","岐阜"],["北陸","富山"],["北陸","福井"],["北陸","石川"]]; ary2 = [["関東",4],["東海",3],["北陸",3]]; for (var i=0; i<ary2.length; i++) { for (var j=0; j<ary2[i][1]; j++) { ary3.push(ary[k]); k++; } ary4.push(ary3); ary3 = []; }

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

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

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

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

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

guest

回答5

0

ベストアンサー

私はご提示のコードで十分だと思います。

考えてみましたが、以下のようなわけのわからないコードになってしまいました。
(ary2を使わない方法)

JavaScript

1var ary = [["関東", "東京"],["関東","神奈川"],["関東","千葉"],["関東","埼玉"],["東海","愛知"],["東海","三重"],["東海","岐阜"],["北陸","富山"],["北陸","福井"],["北陸","石川"]]; 2var ary2 = new Array(); 3var ary3 = new Array(); 4var var k = 0; 5for(var i = 0; i < ary.length; i++){ 6 if(ary2[ary[i][0]] == null){ 7 ary2[ary[i][0]] = k++; 8 } 9 if(ary3[ary2[ary[i][0]]] == null){ 10 ary3[ary2[ary[i][0]]] = new Array(); 11 } 12 ary3[ary2[ary[i][0]]][ary3[ary2[ary[i][0]]].length] = ary[i]; 13}

もしも処理結果が連想配列でもいいのであれば、さらに変数が減らせます。

JavaScript

1var ary = [["関東", "東京"],["関東","神奈川"],["関東","千葉"],["関東","埼玉"],["東海","愛知"],["東海","三重"],["東海","岐阜"],["北陸","富山"],["北陸","福井"],["北陸","石川"]]; 2var ary2 = new Array(); 3for(var i = 0; i < ary.length; i++){ 4 if(ary2[ary[i][0]] == null){ 5 ary2[ary[i][0]] = new Array(); 6 } 7 ary2[ary[i][0]][ary2[ary[i][0]].length] = ary[i]; 8}

連想配列を普通の配列に戻す

JavaScript

1var ary = [["関東", "東京"],["関東","神奈川"],["関東","千葉"],["関東","埼玉"],["東海","愛知"],["東海","三重"],["東海","岐阜"],["北陸","富山"],["北陸","福井"],["北陸","石川"]]; 2var ary2 = new Array(); 3var ary3 = new Array(); 4for(var i = 0; i < ary.length; i++){ 5 if(ary2[ary[i][0]] == null){ 6 ary2[ary[i][0]] = new Array(); 7 } 8 ary2[ary[i][0]][ary2[ary[i][0]].length] = ary[i]; 9} 10for(var key in ary2){ 11 ary3[ary3.length] = ary2[key]; 12}

投稿2015/11/27 06:16

moredeep

総合スコア1507

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

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

KenTerada

2015/11/27 06:32 編集

賛同します.私も連想配列を使うほうがコードが綺麗になるので,好んで使います.連想配列を使うことのオーバヘッドなんてそんなに大きなものではないので. このコードが何万回も実行されてパフォーマンスボトルネックになる,という場合以外は,アルゴリズムとして高速であるよりは,コードが明快で簡潔であるほうが重視されると思います.後々のデバッグのためになりますし,プログラムを書くコストを減らすことができるので.
true

2015/11/27 08:34

ありがとうございます。たとえばary2["関東"]とやると関東グループにアクセスできるということですね。こうゆう使い方には慣れていないので勉強させて頂きます。これがコード的には一番すっきりしますね。じっくり拝見させて頂きます。
guest

0

Ramdaを使っていいのであれば、一行で書けます。

JavaScript

1'use strict'; 2var R = require('ramda'); 3var ary; 4var ary4; 5ary = [["関東", "東京"],["関東","神奈川"],["関東","千葉"],["関東","埼玉"],["東海","愛知"],["東海","三重"],["東海","岐阜"],["北陸","富山"],["北陸","福井"],["北陸","石川"]]; 6ary4 = R.values(R.groupBy(R.head, ary)); 7console.log(ary4);

投稿2015/11/27 10:58

raccy

総合スコア21733

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

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

true

2015/11/27 13:16

これすごいですね。Ramda恥ずかしながら初めて知りました。とっつきやすそうなライブラリで気に入りました。私はどうもライブラリが苦手なのですがこれは良さげです。有益な情報をありがとうございます。
guest

0

ついでにもうひとつ。
副作用なしを目指してみました。

javascript

1 ary.map(function(x){ 2 return x[0]; 3 }) 4 .filter(function(x, i, self){ 5 return i == self.indexOf(x); 6 }) 7 .map(function(x){ 8 return ary.filter(function(y){ 9 return y[0] == x; 10 }); 11 });

投稿2015/11/27 07:15

編集2015/11/27 07:16
Lhankor_Mhy

総合スコア35815

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

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

true

2015/11/27 08:26

ありがとうございます。とてもモダンで興味深いのですが各要素へのアクセスのしかたが分かりませんでした。たとえば関東グループへのアクセスはary[0]とか?ではないですよね。すみません、ついていけませんでした。
Lhankor_Mhy

2015/11/27 09:08

分かりにくくてすみません。戻り値がそのまま結果になっています。 頭に ary4 = などとつけて代入してみてください。
true

2015/11/27 14:31

ありがとうございます。できました!そうやって使うのですね。メソッドチェーンでこんな風につなげられることもすごいと思いました。
guest

0

関東だとかregion_nameが乱雑に出現しないならこれでもいける。

Javascript

1var ary = [["関東", "東京"],["関東","神奈川"],["関東","千葉"],["関東","埼玉"],["東海","愛知"],["東海","三重"],["東海","岐阜"],["北陸","富山"],["北陸","福井"],["北陸","石川"]]; 2var ary2 = new Array(); 3var region_name = ''; 4 5for(var k=0; k < ary.length; k++){ 6 7 if(ary[k][0] != region_name){ 8 region_name = ary[k][0]; 9 ary2.push(new Array()); 10 } 11 12 ary2[ary2.length-1].push(ary[k]); 13}

投稿2015/11/27 07:05

編集2015/11/27 07:17
nage

総合スコア144

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

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

true

2015/11/27 08:28

ありがとうございます。私もロジックとしては前後のregionを比較しながら・・と思いついたのですが具体的にどう書けばいいのかが分かりませんでした。参考にさせて頂きます。
guest

0

そのコードで問題ないような気がしますが、ちょっと書いてみました。

javascript

1 dict={} 2 ary.forEach(function(x){ 3 x[0] in dict ? dict[x[0]].push(x) : dict[x[0]] = [x]; 4 }); 5 Object.keys(dict).map(function(x){ 6 return dict[x]; 7 })

投稿2015/11/27 06:41

Lhankor_Mhy

総合スコア35815

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問