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

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

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

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

Q&A

解決済

2回答

1561閲覧

ある数列に存在しない数字を返す処理がうまくいかない

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

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

1グッド

0クリップ

投稿2016/08/26 15:34

編集2016/08/26 15:43

JavaScript

1// nums1は1~9までの数が重複せずに入る 2// 0は空白のつもり 3var nums1 =[ 4 [3, 0, 7, 4, 9, 0, 0, 5, 8], 5 [0, 1, 2, 3, 5, 8, 4, 7, 6], 6 [8, 5, 0, 6, 7 ,1, 3, 2, 9] 7]; 8function getNum1(arr, c) { 9 var num = [1, 2, 3, 4, 5, 6, 7, 8 ,9]; 10 var numlen = num.length; 11 var len = arr.length; 12 for (var i = 0; i < len; i++) { 13 if (arr[c][i] == 0) continue; 14 for (var j = 0, l = num.length; j < l; j++) { 15 if (num[j] == arr[c][i]) { 16 num[j] == null; 17 del_Arr(num, null); 18 break; 19 } 20 } 21 } 22 return num; 23} 24console.log(getNum1(nums1, 0)); 25// [1, 2, 3, 4, 5, 6, 7, 8, 9] 26 27function getNum2(arr, c, e) { 28 var num = [1, 2, 3, 4, 5, 6, 7, 8 ,9]; 29 var numlen = num.length; 30 var len = arr.length; 31 for (var i = 0; i < e; i++) { 32 for (var j = 0, l = num.length; j < l; j++) { 33 if (num[j] == arr[c][i]) num[j] = null; 34 } 35 } 36 del_Arr(num, null); 37 for (var i = e+1; i < len; i++) { 38 for (var j = 0, l = num.length; j < l; j++) { 39 if (num[j] == arr[c][i]) num[j] = null; 40 } 41 } 42 del_Arr(num, null); 43 return num; 44 } 45 46console.log(getNum2(nums1, 0, 1)); // 0の場所を指定している 47// [1, 2, 6] 48 49 50function delArr(arr, target) { 51 for (var i = 0, l = arr.length; i < l; i++) { 52 if (arr[i] == target) { 53 arr.splice(i, 1); 54 delArr(arr, target); 55 } 56 } 57} 58/* 59 * delArrには自信がありませんので評価をお願いしてもよろしいでしょうか...? 60 */

配列num1[i]に存在しない数値を返すプログラムを作っているのですが、関数getNum1のように書くと、関数内のnumがそのまま返されてしまいます。
関数getNum2のように存在しない数だけを返したいのですが、何が間違っているのですか?

kei344👍を押しています

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

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

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

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

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

guest

回答2

0

ベストアンサー

  • 文法エラー

javascript

1if (num[j] == arr[c][i]) { 2 num[j] == null; // 代入ではなく比較になっている

javascript

1del_Arr(num, null); // delArr //getNum2も同様

これで、 [1, 2, 4, 5, 6, 8, 9] になります。

あとバグとして

javascript

1var len = arr.length; //見てる次元が違うので3が返る。arr[c].lengthが正しいはず 2for (var i = 0; i < len; i++) { 3 if (arr[c][i] == 0) continue;

これで正解になります。間違いについては以上です。

追記

詳しくは調べてもらうとして、少し追記してみます。
配列からある値の位置を調べるには、Array.indexOf() が使えます。
これは0以上ならば見つかったインデックス。見つからないときは-1を返すので、

delArrは以下の様に書けます。

javascript

1function delArr(arr, target) { 2 while(arr.indexOf(target) >= 0) 3 arr.splice(arr.indexOf(target),1); 4}

whileしているのは、arrにtargetが複数見つかる可能性がある場合に備えてです。
あったとしてもかならず1つしか無いのであれば、whileはいりません。

細かいところだと、値の比較は === の方が厳格に比較されます。
ざっくりいうと、 == だと0っぽいもの( 0に自動変換可能なもの。例えば 文字列 "0" ) も一致とみなされますが、=== だと数値の 0以外違うものとされます。
今回のケースでは厳密に比較したいと思うので===の方が良いでしょう。

javascript

1// if (arr[c][i] == 0) continue; 2if (arr[c][i] === 0) continue;

以下は参考です。
ちょっと久々にjavascriptでリスト操作関数書いてみたくなったので。
いろいろと便利な関数があるのでその紹介と思ってください。

まず、filterを使うと、値一つ一つをfilter内の関数に処理させて、関数がtrueを返さないものは除外することができます。
(その名の通りフィルターになります)

javascript

1function getNum3(arr) { 2 var num = [1, 2, 3, 4, 5, 6, 7, 8 ,9]; 3 var filtered= num.filter(function(x) { 4 return arr.indexOf(x) == -1; 5 }); 6 return filtered; 7} 8 9console.log(getNum3(nums1[0]));

随分短くなりましたが、新しいバージョンのjavascript (ES6とか言われます)のアロー関数を使うともっと短くなります。

javascript

1function getNum3Arrow(arr) { 2 var num = [1, 2, 3, 4, 5, 6, 7, 8 ,9]; 3 return num.filter(x => arr.indexOf(x) == -1); 4} 5 6console.log(getNum3Arrow(nums1[0]));

あと、reduceというリストの集計などに使われる関数もあり、それを使うと以下の様にも書けます。
reduceは説明が長くなりそうなので興味があれば調べてみてください。
(初期値を配列にしているので、説明しやすい素直なreduceでもないので)

javascript

1function getNum4(arr) { 2 var num = [1, 2, 3, 4, 5, 6, 7, 8 ,9]; 3 var result = num.reduce(function(prev, next){ 4 if(arr.indexOf(next) == -1){ prev.push(next); } 5 return prev; 6 }, []); 7 return result; 8} 9 10console.log(getNum4(nums1[0]));

関数を渡してますが、nextにリストの要素が一つ一つはいってきます。filterのときみたいに。
prevは、一つ一つ処理する中で、この関数で前回returnしたものが入ってきます。
最後に指定する引数は(今回は []) は初期値です。「前回returnしたもの」と言っても、一番最初は何もreturnしてないですよね。そういうことです。最初のprevに使われます。

やってることはfilterと同じです。 indexOfの結果が -1だったらprevに回ってきたリストにそれを詰めて次、indexOfの結果が -1だったらprevに回ってきたリストにそれを詰めて次・・・です。

長々失礼しました。こんな書き方もありますよ、という参考にどうぞ。

動くものも置いておきます。動かないときは [Run with JS] ボタンで動きます。
http://jsbin.com/riveheqipo/edit?js,console,output

投稿2016/08/26 15:51

編集2016/08/26 16:25
flied_onion

総合スコア2604

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

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

退会済みユーザー

退会済みユーザー

2016/08/26 15:58

回答ありがとうございます!! 比較演算になってたところを見落としていました!! arr[c].length;にしなければならないことをすっかり忘れていました...助かりました!! とても参考になりました!ありがとうございます!!
退会済みユーザー

退会済みユーザー

2016/08/26 16:27

とても参考になりました!!!! ありがとうございます!!!
guest

0

作るべきは、シンプルな配列を渡した時に、存在しない数値をまとめた新しい配列を返す関数ではないかなと。

JavaScript

1var nums1 =[ 2 [3, 0, 7, 4, 9, 0, 0, 5, 8], 3 [0, 1, 2, 3, 5, 8, 4, 7, 6], 4 [8, 5, 0, 6, 7 ,1, 3, 2, 9] 5]; 6function getNum(arr) { 7 var num = [1, 2, 3, 4, 5, 6, 7, 8 ,9]; 8 9 var result = num.map(function(item, index){ 10 if(arr.indexOf(item) < 0) { 11 return item; 12 } 13 }).filter(function(item){ 14 return typeof item === 'number'; 15 }); 16 17 return result; 18} 19var array = nums1[0]; // [3, 0, 7, 4, 9, 0, 0, 5, 8] 20console.log(getNum(array)); 21// [1, 2, 6] 22 23/* まとめて抽出 */ 24var nonExistNumArr = nums1.map(function(item){ 25 return getNum(item); 26}); 27 28console.log(nonExistNumArr); // [[1, 2, 6], [9], [4]]

投稿2016/08/26 16:08

編集2016/08/26 16:16
yamato_hikawa

総合スコア2092

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

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

退会済みユーザー

退会済みユーザー

2016/08/26 16:16

ありがとうございます。 それは私の技術不足というのと、なるべく組み込みの機能を使わずに開発をしようと思いまして...
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問