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

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

ただいまの
回答率

89.98%

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

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,120

Satochan24

score 84

['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で可能なのか不明ですが…

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Satochan24

    2016/01/07 17:25 編集

    カウントさせればできるのではないかと思い、
    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)
    {
    }
    }
    }
    まで作ったのですが、カウント後の処理で悩んでいます。

    キャンセル

回答 4

checkベストアンサー

+1

var 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]];

arr.filter(function(row){
  return row.slice(1).reduce(function(sum,v){
    return sum | v;
  });
})


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

追記

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

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


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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/01/07 18:13 編集

    回答有難うございます。
    このように、'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)]

    キャンセル

  • 2016/01/07 18:55

    追記します。

    キャンセル

  • 2016/01/08 14:50

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

    キャンセル

+1

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

var 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]
  ];
(function (){
  var len = arr.length;
  while(len){
    len--;
    var arr_c = arr[len].concat();
    arr_c.shift();
    if(('' + arr_c).split('0,').join('') == '0'){
      arr.splice(len,1);
    }
  }
}());

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/01/08 11:14

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

    キャンセル

  • 2016/01/08 12:00

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

    キャンセル

  • 2016/01/08 17:55

    >think49さん
    コメントありがとうございます。
    質問者から提示されたデータ構成のみを対象として組んでいますのでその形のデータが混入した場合、破綻する可能性はあると思います。
    今回そのような例外は発生しないものとして組んであります。
    理由として既に別回答に良いものがある点(ですのでこのコードは参考程度に書いてみたものです)、どのような例外があり得るかを考えるとキリがない点、resultという変数名からデータがプログラムによって生成されている可能性(人的ミスによる例外が発生しない)という想定があります。

    >Satochan24さん
    whileは二次元配列をループしています。
    その際、内部配列をコピーします。
    コピーした物から先頭要素を削除します。
    それを配列から文字列に変換し、"0,"で分割、""(空文字列)で結合します。
    そうすることにより、0のみの配列は以下のように変化します。
    "0,0,0,0,0,0,0,0" → "0"(最後の"0"のみ残る)
    こうすることで0のみの配列を検出し、該当した場合は元の配列から該当したインデックスの要素を削除しています。

    キャンセル

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 17: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の処理を入れる
    }
    }
    }

    キャンセル

0

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

'use strict';
function sample1 (array) {
  return array.filter(function (array) {
    var i = array.length;

    while (--i) {
      if (array[i] !== 0) {
        return true;
      }
    }

    return false;
  });
}

function sample2 (array) {
  return array.filter(function (array) {
    return array.join() !== String(array[0]) + ',0,0,0,0,0,0,0,0';
  });
}

var array = [
      ['Month','メニュー(101)','(102)','(103)','(201)','(202)','(203)','(204)','(301)'],
      ['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]
    ];

console.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]]
console.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/08 12:15

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

    キャンセル

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

  • ただいまの回答率 89.98%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる