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

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

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

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

Q&A

解決済

5回答

2351閲覧

javascriptの綺麗な書き方

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

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

2グッド

2クリップ

投稿2019/03/26 08:31

編集2019/03/26 08:53

前提・実現したいこと

配列で遊んでいるのですが、参考にいろんな書き方を教えてもらえますか。
やっていることは、配列のチャンクをとって、各チャンクの最大値を取っています。
ただ、余剰も残さず最大値を引っ張っています。

該当のソースコード

javascript

1const array1 = [1,2,3,4,5,6,7,8,9,10,11] 2 3const num = 3; 4const array2 = new Array(); 5 6let i = array1.length; 7 8for(var n = 0 ; n < i ; n++) { 9 10 if(array1.length < num ) { 11 memo = Math.max(...array1); 12 array2.push(memo); 13 i = 0; 14 } else { 15 let memo = array1.splice(0, num); 16 memo = Math.max(...memo); 17 array2.push(memo); 18 } 19} 20 21console.log('array2 = ' + array2)

補足

上のコードは期待した通りに動くのは動いてます。

reraNine👍を押しています

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

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

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

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

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

stdio

2019/03/26 08:40

なら自分で調べて遊びましょう。そうしないといつまで経っても成長はしませんよ。
退会済みユーザー

退会済みユーザー

2019/03/26 08:43

そうですね。他の人たちが、どう言う風に書くか興味があって聞いたんですが、それですらダメみたいですね。
stdio

2019/03/26 08:56

一般の人からしたら出来たらなんでも良いと思われている世界でその質問は無しですよ。 配列の書き方なんて言語によってコロコロ変わりますし、javascriptのやり方も人それそれです。 ショートコードが書きたいのか、エラーを嫌ってしっかり型確認と型変換を欠かさず行う人とか色々いますよ。
退会済みユーザー

退会済みユーザー

2019/03/26 09:48

提示されているコードは JavaScript っぽくないから、他言語からの人ですかね?おれはこういう質問ワリと好きw
退会済みユーザー

退会済みユーザー

2019/03/26 09:59

おっしゃる通りぶっちゃけるとjavascriptはあんまり触ったことはないですw ついでにプログラムに触レたのも数年ぶりで、しっちゃかめっちゃかなコードで、時間を置いた上で頂いた指摘も踏まえて読み直すとウンコードで恥ずかしいですね。ウンコードに掲載されたいです。
guest

回答5

0

ベストアンサー

質問文をレビューするとこんな感じです。

  • 細かいですが空配列は[]を使って宣言しましょう。
  • ループの継続条件は一目で読み取れるようにしましょう、詳しくは後述
  • for文の中身はifとelseで同じ事やってますね。ダサいので共通化しましょう、詳しくは後述

for文の第二節はループの継続条件です。
質問文では変数nの数値が0から始まり、変数iを超えた場合に終了すると書かれています。
array1の要素数は11なので、100人のエンジニアに読ませれば全員が「ああ、この場面では11回ループを回したいのね」と判断をするでしょう。

実際にやってる事はガンガンarray1の要素数が取り除かれて、
要素数が2以下になったら突如i = 0が実行されてループが切れます。
i = 0にするくらいならbreak文使えよとなるのですが
そもそも11回ループを回すと書かない方が良いです。

また、if文の中身は[1, 2].splice(0, 3)がエラーを出すのを懸念しているのでしょうか?
これの結果は元気に[1, 2]を返しますし、元の配列は空配列になります。
つまりif文による分岐は不要です。

この辺の事情から変数i,nをそもそも使わず、
array1をガンガン削りますよという宣言の元、
array1.length != 0みたいな式に変更した方がわかりやすくなるでしょう。

上記を加味して書き直すとこうなります。

JavaScript

1const array1 = [1,2,3,4,5,6,7,8,9,10,11]; 2const num = 3; 3const array2 = []; 4 5while (array1.length != 0) { 6 array2.push(Math.max(...array1.splice(0, num))); 7} 8console.log(array2); 9// [3, 6, 9, 11]

ちなみにLodashを使えばワンライナーです。

JavaScript

1_.chain(1) 2 .range(12) 3 .chunk(3) 4 .map(its => Math.max(...its)) 5 .tap(console.log) 6 .value(); 7// [3, 6, 9, 11]

投稿2019/03/26 08:58

編集2019/03/26 09:34
miyabi-sun

総合スコア21158

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

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

miyabi-sun

2019/03/26 09:06

今回はwhile文の中身を一撃で書きましたが、 この辺が評価が分かれるところで、 何か一時的に`tmpArray`みたいな配列を宣言して受ける程度に派生するでしょうが、 ALGOLらしく解くなら大抵はこの形に落ち着くと思います。
退会済みユーザー

退会済みユーザー

2019/03/26 09:22

ありがとうございます。とっても参考になります。Lodashってのがあるんですね。面白いですね。 ifの中身はwhileを使わずに書いたため、おっしゃる通りエラーが返ってくるので、書いていました。
miyabi-sun

2019/03/26 09:27

回答書いてる最中に理解したのですが、 エラーを消すために`i = 0`を入れたというのがより正しい形ですね。 少し回答を修正して対応します。
退会済みユーザー

退会済みユーザー

2019/03/26 09:31

ご丁寧にありがとうございます。^^
guest

0

コーディング方法

おそらく、コーディングの手順に問題があります。
他言語経験者のようですが、「JavaScript固有の機能を知らずに無駄な書き方をしてしまった」というより「場当たり的にコードを付け加え続けた為にアルゴリズム上の無駄を生産してしまった」という印象を持ちました。
「アルゴリズム上の無駄」はコードを書く前に熟考して排除すべきなので、コーディング前の準備が必要と感じます。

  • 大体のロジックを紙に書きだす
  • フローチャートを作る

改善点

未出の改善点としては、配列の昇順ソートが保証されているのなら、+-3でindex値を走査すれば良いでしょう。

JavaScript

1const input = [1,2,3,4,5,6,7,8,9,10,11], results = [], l = input.length, diff = l % 3; 2let i = l - 1; 3 4results.push(input[i]); 5 6if (diff) { 7 results.unshift(input[i = i - diff]); 8} 9 10while ((i -= 3) > -1) { 11 results.unshift(input[i]); 12} 13 14console.log(results); // [3, 6, 9, 11]

配列の昇順ソートが保証されていないのなら、毎回、index=0から最大値を求める無駄を排除するコードを書けます。

JavaScript

1const input = [1,2,3,4,5,6,7,8,9,10,11], results = []; 2let max = Math.max(...input.slice(0, 3)); 3 4results.push(max) 5for (let i = 3, len = input.length; i < len; i += 3) { 6 results.push(max = Math.max(max,...input.slice(i, i + 3))); 7} 8 9console.log(results); // [3, 6, 9, 11]

コードを書きましたが、前述の通り、omaru3 さんの場合は「他人の良いコードの書き方を盗む」よりも「一からアルゴリズムを考えてコーディングする」が必要な段階だと私は思います。

Re: omaru3 さん

投稿2019/03/26 12:53

think49

総合スコア18162

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

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

0

最短?

javascript

1console.log([1,2,3,4,5,6,7,8,9,10,11].reduce((a,b,i)=>(i=i/3|0,(a[i]||0<b?a[i]=b:0),a),[]));

投稿2019/03/26 09:29

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2019/03/26 09:33

92文字ですか!最短ですね。ありがとうございます。
guest

0

javascript

1((r,j) => r.reduce((a,b,i,g) => !(i % j) ? a.concat([g.slice(i,i+j)]) : a, []))([1,2,3,4,5,6,7,8,9,10,11], 3).map(e=>Math.max(...e));

やっていることは、範囲指定した配列から最大値を抜き出して、別の配列に突っ込んでいます。

やっていることは、配列のチャンクをとって、各チャンクの最大値を取っている、です。

投稿2019/03/26 08:44

編集2019/03/26 08:47
papinianus

総合スコア12705

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

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

退会済みユーザー

退会済みユーザー

2019/03/26 08:52

凄いコードですね。ありがとうございます。
papinianus

2019/03/26 09:07 編集

綺麗じゃないからマイナスなのか。 > 参考にいろんな書き方 に答えたつもりです。
退会済みユーザー

退会済みユーザー

2019/03/26 10:50

このコードに刺激されて短く書きました。評価しておくね。
guest

0

php 脳が書くとこんな感じ

JavaScript

1const array1 = [1,2,3,4,5,6,7,8,9,10,11]; 2const array2 = []; 3const num = 3; 4let count = 0; 5 6array1.forEach((val, key)=>{ 7 if(key % num === 0){ 8 count = (key === 0) ? 0 : count + 1; 9 array2[count] = 0; 10 } 11 array2[count] = array2[count] > val ? array2[count] : val; 12}); 13console.log(array2);

投稿2019/03/26 13:48

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問