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

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

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

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

Q&A

解決済

4回答

3817閲覧

【JavaScript】2次元配列の2番目以降の数値が全てゼロの場合に、その行を削除したい。

Satochan24

総合スコア113

JavaScript

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

0グッド

0クリップ

投稿2016/01/07 07:36

編集2016/01/07 08:36

['this',0,0,0,0,0,0,0,0],['one',16,8,1,6,0,0,0,1],['two',76,44,22,40,16,12,1,8],['three',59,6,5,15,2,4,2,4],['four',26,0,0,0,0,0,0,5],['five',59,0,0,0,0,0,0,18],['six',0,0,0,0,0,0,0,0],['seven',0,0,0,0,0,0,0,0]

このような配列resultがあるのですが、
これを、

['one',16,8,1,6,0,0,0,1],['two',76,44,22,40,16,12,1,8],['three',59,6,5,15,2,4,2,4],['four',26,0,0,0,0,0,0,5],['five',59,0,0,0,0,0,0,18]

のように、データがある行だけに絞りたいです。

var count = 0; for(var l = 1; l < result.length; l++){ for(var m =1 ; m < result[l].length; m++){ if(result[l][m]== 0){ count++; //result.spice() } if (count == result[l].length -1) { //ここにspiceの処理を入れる } } }

のように途中まで作ってみたのですが、spiceの処理で悩んでいます。そもそも、spiceで可能なのか不明ですが…

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2016/01/07 07:52

こちらの質問が他のユーザから「質問の範囲が広すぎる」という評価を受けています わからない点を明確にし、調査したこと・試したことと共に記入していただくと、回答が得られやすくなります。
Satochan24

2016/01/07 08:26 編集

カウントさせればできるのではないかと思い、 var count = 0; for(var l = 1; l < result.length; l++){ for(var m =1 ; m < result[l].length; m++){ if(result[l][m]== 0){ count++; } if (count == result[l].length -1) { } } } まで作ったのですが、カウント後の処理で悩んでいます。
guest

回答4

0

他の方が既に綺麗な答えを投稿しているので黒魔術で回答。

javascript

1 var arr = [ 2 ['this',0,0,0,0,0,0,0,0], 3 ['one',16,8,1,6,0,0,0,1], 4 ['two',76,44,22,40,16,12,1,8], 5 ['three',59,6,5,15,2,4,2,4], 6 ['four',26,0,0,0,0,0,0,5], 7 ['five',59,0,0,0,0,0,0,18], 8 ['six',0,0,0,0,0,0,0,0], 9 ['seven',0,0,0,0,0,0,0,0] 10 ]; 11(function (){ 12 var len = arr.length; 13 while(len){ 14 len--; 15 var arr_c = arr[len].concat(); 16 arr_c.shift(); 17 if(('' + arr_c).split('0,').join('') == '0'){ 18 arr.splice(len,1); 19 } 20 } 21}());

投稿2016/01/07 18:34

Cf_cwd

総合スコア730

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

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

think49

2016/01/08 02:14

> if(('' + arr_c).split('0,').join('') == '0'){ その書き方ですと、var arr = [['hoge',0,0,0,0,0,0,0,'0,0']]; で破綻するのではないでしょうか。
Satochan24

2016/01/08 03:00

回答ありがとうございました。 実行して確認しました。 処理してる内容が完全に把握できなかったですが、 1行づつステップインできる実行環境があれば、 把握しやすく、開発もしやすくなると思いました。
Cf_cwd

2016/01/08 08:55

>think49さん コメントありがとうございます。 質問者から提示されたデータ構成のみを対象として組んでいますのでその形のデータが混入した場合、破綻する可能性はあると思います。 今回そのような例外は発生しないものとして組んであります。 理由として既に別回答に良いものがある点(ですのでこのコードは参考程度に書いてみたものです)、どのような例外があり得るかを考えるとキリがない点、resultという変数名からデータがプログラムによって生成されている可能性(人的ミスによる例外が発生しない)という想定があります。 >Satochan24さん whileは二次元配列をループしています。 その際、内部配列をコピーします。 コピーした物から先頭要素を削除します。 それを配列から文字列に変換し、"0,"で分割、""(空文字列)で結合します。 そうすることにより、0のみの配列は以下のように変化します。 "0,0,0,0,0,0,0,0" → "0"(最後の"0"のみ残る) こうすることで0のみの配列を検出し、該当した場合は元の配列から該当したインデックスの要素を削除しています。
guest

0

ベストアンサー

javascript

1var arr= [['this',0,0,0,0,0,0,0,0],['one',16,8,1,6,0,0,0,1],['two',76,44,22,40,16,12,1,8],['three',59,6,5,15,2,4,2,4],['four',26,0,0,0,0,0,0,5],['five',59,0,0,0,0,0,0,18],['six',0,0,0,0,0,0,0,0],['seven',0,0,0,0,0,0,0,0]]; 2 3arr.filter(function(row){ 4 return row.slice(1).reduce(function(sum,v){ 5 return sum | v; 6 }); 7})

算術和だとダメだけど、論理和なら紛れがない、はず。



#####追記
コメントを受けて、タイトル行を残す方法です。

javascript

1arr.filter(function(row, i){ //この行を変更 2 return (i==0) || row.slice(1).reduce(function(sum,v){ //この行を変更 3 return sum | v; 4 }); 5});

 または最初のコメントで書いた方法でも残ると思いますが、ちょっと気持ちが悪いので書き直してみました。こんな感じで。

javascript

1arr.filter(function(row, i){ 2 return row.slice(1).reduce(function(flag,v){ 3 return flag || ( v !== 0 ); 4 },false); 5});

投稿2016/01/07 08:13

編集2016/01/07 10:17
Lhankor_Mhy

総合スコア35865

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

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

Lhankor_Mhy

2016/01/07 08:27

型を見ないのはバグの温床かなあ? return sum + ( v !== 0 ) とかの方がいいかなあ←
Satochan24

2016/01/07 08:28

回答、有難うございます。 見たことない方法で驚いたのですが、 試してみたら、削除されていませんでした。 自分の記入ミスかもしれないと調べています。
MasahiroHarada

2016/01/07 08:36 編集

filterメソッドの戻り値を新しい変数に代入してやれば、その変数はデータがある行だけに絞られた状態になっていると思います。
Lhankor_Mhy

2016/01/07 08:50

分かりにくくて申し訳ないです。MasahiroHaradaさんのおっしゃる通りです。元の配列は破壊しません。 var arr2 = arr.filter(function(row){... とかしてください。
ipadcaron

2016/01/07 09:09

reduce の使い方が勉強になりました。 1|undefined 1|"" undefined|1 null|1 が1になるのは気持ち悪いですね。>紛れがない、に対して。 ってことは、算術和ノー場合は、ノイズ検出に利用できまづね。 ありがとうございまぢた。
Satochan24

2016/01/07 09:17 編集

回答有難うございます。 このように、'one',16,8,1,6,0,0,0,1,'two',76,44,22,40,16,12,1,8,'three',59,6,5,15,2,4,2,4 できたのですが… 実は、最初の行に項目名となるデータがありまして、これまで削除されてしまったのですが…何か対処方法ありますでしょうか? 【削除された1行目】 ['Month',メニュー(101),(102),(103),(201),(202),(203),(204),(301)]
Satochan24

2016/01/08 05:50

回答ありがとうございました。 こんな短いコードで実現できることに驚きました!
guest

0

要件は「0 埋め値の削除」ですが、逆転の発想で 値に 0 を含まない時に残すコードにするとすっきりするように思います。

JavaScript

1'use strict'; 2function sample1 (array) { 3 return array.filter(function (array) { 4 var i = array.length; 5 6 while (--i) { 7 if (array[i] !== 0) { 8 return true; 9 } 10 } 11 12 return false; 13 }); 14} 15 16function sample2 (array) { 17 return array.filter(function (array) { 18 return array.join() !== String(array[0]) + ',0,0,0,0,0,0,0,0'; 19 }); 20} 21 22var array = [ 23 ['Month','メニュー(101)','(102)','(103)','(201)','(202)','(203)','(204)','(301)'], 24 ['this',0,0,0,0,0,0,0,0], 25 ['one',16,8,1,6,0,0,0,1], 26 ['two',76,44,22,40,16,12,1,8], 27 ['three',59,6,5,15,2,4,2,4], 28 ['four',26,0,0,0,0,0,0,5], 29 ['five',59,0,0,0,0,0,0,18], 30 ['six',0,0,0,0,0,0,0,0], 31 ['seven',0,0,0,0,0,0,0,0] 32 ]; 33 34console.log(JSON.stringify(sample1(array))); // [["Month","メニュー(101)","(102)","(103)","(201)","(202)","(203)","(204)","(301)"],["one",16,8,1,6,0,0,0,1],["two",76,44,22,40,16,12,1,8],["three",59,6,5,15,2,4,2,4],["four",26,0,0,0,0,0,0,5],["five",59,0,0,0,0,0,0,18]] 35console.log(JSON.stringify(sample2(array))); // [["Month","メニュー(101)","(102)","(103)","(201)","(202)","(203)","(204)","(301)"],["one",16,8,1,6,0,0,0,1],["two",76,44,22,40,16,12,1,8],["three",59,6,5,15,2,4,2,4],["four",26,0,0,0,0,0,0,5],["five",59,0,0,0,0,0,0,18]]

sample2()String 型に変換して評価するのでプリミティブ値外の値を含んでいると厳密ではありません。
通常は sample1() を使う事になると思います。

(index 0 の要素を残す)
「最初の行に項目名となるデータがある』との事ですが。見たところ0埋めデータではないようなので特別措置はしていません。
必要なら、array.shift() で退避させてください。

Re: Satochan24 さん

投稿2016/01/07 11:39

think49

総合スコア18156

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

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

Satochan24

2016/01/08 03:15

回答ありがとうございました。 実行して確認しました。 こういう、テクニカルな部分はどうやれば身につくのかと改めて 考えさせられました。 なかなか本にも載ってないし、WEBで調べても必ずしも出てこないし…
guest

0

手順だけ。
新しい配列用意 var newArray = [];
result.forEach(function(element, index) {}); で2次元配列の縦を評価。
上記のfunction 内で、var count = 0; を宣言。
element は2次元配列の内側の配列、横軸なので、これを更に、element.forEach。
上記の fubction 内で、index > 0 かつ element == 0 のとき、count++
内側のループ完了後、count == 外側の element.length - 1 の逆の要素を newArray に格納。

投稿2016/01/07 08:03

ipadcaron

総合スコア1693

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

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

Satochan24

2016/01/07 08:33

回答有難うございます。 チョット分かりにくかったのですが、やはり多少面倒な処理が必要なんですね。 私が途中まで考えた、カウントする方法で、spice()メソッドで 何とかできないかなと悩んでいます。 この方法でも可能でしょうか? var count = 0; for(var l = 1; l < result.length; l++){ for(var m =1 ; m < result[l].length; m++){ if(result[l][m]== 0){ count++; //result.spice() } if (count == result[l].length -1) { //ここにspiceの処理を入れる } } }
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問