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

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

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

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

Q&A

解決済

2回答

1040閲覧

JavaScriptで作った任意の配列から重複する要素を取り除いた後、何種類の数値で構成されている確認するためのプログラミングの解説をお願いします。

echizeyayota

総合スコア106

JavaScript

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

0グッド

1クリップ

投稿2021/09/04 07:25

いつもお世話になっています。
下記の質問についてご存知の方がいらっしゃいましたらご教示を願います。


【質問の主旨】

ある配列内において重複する数値の要素を除いたのち、その配列がもともといくつの要素で構成されているかカウントするプログラムがあります。

const arr = [2, 3, 4, 4, 5] var removeDuplicates = function(nums) { for (let i = 0; i < nums.length; ++i) { while(nums[i] === nums[i + 1]) { nums.splice(i + 1, 1); } } return nums.length; }; console.log(removeDuplicates(arr)); // 4

なぜこのコードで、定数arrは4つの要素から成る配列であることが判定できるのでしょうか?

【質問の補足】

1. このアルゴリズムとプログラミングについて

このアルゴリズムはleetcodeから引用し、プログラミングコードはこの問題について解答をされた方のコードを引用しています。leetcode上ではこのコードは「正解(Accepted)」とされます

イメージ説明

leetcode上ではこのコードは「正解」とされています。

2. spliceで処理をしたあとの配列値について

特にwhile文の中で、nums.splice(i + 1, 1); としたあとの配列が[2, 3, 4, 5]となることは理解できますが、その配列が別の変数に代入されているわけではないにもかかわらず、return nums.length; したときにはすでに要素の個数が5から1つ減って4になっていることがよくわかりません。

3. デバッグについて

nums.splice(i + 1, 1); について確認するために、paiza.ioを使ってデバッグをしました。
するとこちらは処理結果の配列や、その要素数も想定外の結果が返されます。leetcode と paizo.io でなぜ異なるような挙動をするのかよく分かりません。

イメージ説明


以上、よろしくお願いします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

spliceは配列を破壊的に書き換えます(詳しい仕様についてはMDNが分かりやすいです)。つまり、nums.splice(i + 1, 1);を実行した時点で既にnumsの内容が[2, 3, 4, 5]に変更されています。そのため、それよりも後ろにあるnums.length;では4が出力されます。
また、leetcodeとpaiza.ioで結果が異なるように見えるのは、console.log(nums.splice(i + 1, 1))を追加したからです。これによって2回配列を書き換えることになっています。この行をconsole.log(nums)に変更すると期待通りに出力されるはずです。

このコードの仕組みが分かりやすくなるように出力する部分を増やしてみたので実際にarrの中身を色々と変更して実行してみてください。

js

1const arr = [2, 3, 4, 4, 5, 5, 5] 2 3var removeDuplicates = function(nums) { 4 5 for (let i = 0; i < nums.length; ++i) { 6 console.log(`配列[${nums}]の${i}番目と重複したデータがないかチェックします`) 7 while(nums[i] === nums[i + 1]) { 8 nums.splice(i + 1, 1); 9 console.log(` 配列[${nums}]の${i}番目と${i+1}番目のデータは重複していたので${i+1}番目のデータを削除しました`) 10 console.log(` 現在の内容:[${nums}]`) 11 12 } 13 } 14 15 return nums.length; 16 17}; 18 19console.log(removeDuplicates(arr)); 20

投稿2021/09/04 09:07

goma1661

総合スコア167

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

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

echizeyayota

2021/09/05 02:26

goma1661 さん。 コメントありがとうございます。 また元のコードから、for や while で何をやっているのか分かりやすいコードに書き換えてくださりありがとうございます。このコードを確認することで自分が疑問に思っていたことが全て解消しました。 今後ともどうぞよろしくお願いします。
guest

0

2枚目の画像の「本来は[2,3,4,5]と整数値の4が表示されるのでは?」というコメントより
誤解があるかもしれませんので、

spliceは、(配列と与える引数によりますが)
元の配列そのものを破壊的に変更するとともに、
spliceの戻り値は、変更された後の配列ではなく、切り取られた要素の配列です。

const arr = [0, 1, 2, 3, 4]; const a = arr.splice(2, 1); console.log(a) //[2] と出力される =切り取った要素が配列として返される。 console.log(arr) //[0, 1, 3, 4] と出力される =元の配列が破壊的に変更されている

投稿2021/09/04 11:30

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

echizeyayota

2021/09/05 02:26

baitokunさん spliceの解説ありがとうございます。 おかげさまでspliceメソッドがどういう性質のメソッドであるかがよく分かりました。 今後ともどうぞよろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問