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

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

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

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Q&A

解決済

2回答

1793閲覧

reduceで配列を組み替えたいのですが、上手く行きません。

yuki_90453

総合スコア326

JavaScript

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

0グッド

0クリップ

投稿2019/10/14 11:16

編集2019/10/14 11:20

###目的
下記のように①の配列を2件ごとに区切って②の配列のように書き変えたいと思います。
①["aaa","bbb","ccc","ddd"]
②[["aaa","bbb"],["ccc","ddd"]]

###方法
TypeScriptで書いているのですが、下記のように書くと、tableの型がneverになってしまい上手く行きません。

let sku_list = ["aaa","bbb","ccc","ddd"]; let sku_list_per_limit = sku_list.reduce((table, item) => { let last :Array<string> = table[table.length - 1]; console.log(last); if((last.length % 2) === 0) { table.push([item]); return table; } last.push(item); return table; }, [[]]);

###質問
解決方法がわからず途方にくれています。
① reduceメソッドの 戻り値の累積変数の型を指定方法はありますでしょうか?
上記のコードの末尾 [[]]の事です。

② reduceメソッドを使った方がわかりやすいと聞いて作ってみたのですが、私のコードは非常に見づらくわかりにくいです。わかりやすいように書きたいのですが、ご指摘頂けないでしょうか?

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

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

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

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

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

guest

回答2

0

ベストアンサー

こんにちは

まず、

① reduceメソッドの 戻り値の累積変数の型を指定方法はありますでしょうか?
上記のコードの末尾 [[]]の事です。

については、

javascript

1sku_list.reduce((table, item) => {

の、reduceに与えている関数の引数 tableitem に型指定を追加して

typescript

1sku_list.reduce((table: string[][], item: string) => {

としてみるといかがでしょうか?次に、

② reduceメソッドを使った方がわかりやすいと聞いて作ってみたのですが、私のコードは非常に見づらくわかりにくいです。わかりやすいように書きたいのですが、ご指摘頂けないでしょうか?

については、以下の6つのコード例を順に挙げます。

  1. yuki_90453さんがご質問に挙げられているコードに近いもの(reduceを使用)
  2. 上記 1. の reduceに与える関数の、コード行を減らしたもの
  3. reduce の替わりに、map と filter を使用する例
  4. 文字列を経由して、正規表現によるreplaceおよび split, map を使う例
  5. loadsh_.chunk を使用した例
  6. 上記 5. の _.chunk と同様な関数を自作

なお上記のうち、3, 4, 5, 6 は、reduce を使わないコードになっています。

コード例 1

まずはじめに、yuki_90453さんがご質問に挙げられているコードに近いものを挙げます。(なお、以下のコードでは、ご質問のコードでは table という変数を、短い変数名の t にしています。)

typescript

1type StrAry = string[] 2 3const ary: StrAry = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg'] 4 5const ary2: StrAry[] = ary.reduce((t: StrAry[], str: string, i: number) => { 6 if (i % 2 === 0) { 7 return [...t, [str]] 8 } 9 t[t.length - 1].push(str) 10 return t 11}, []) 12 13console.log(ary2) 14

私の手元の動作確認ですと、上記にて、型指定のエラー、警告などが出ることなく、意図した結果が得られました。

コード例 2

以下は、先のコード例1の reduce に与える関数本体で、 return を使わないで済ませるようにしたものです。行数は減りましたが、可読性に難アリかもしれません。

typescript

1type StrAry = string[] 2 3const ary: StrAry = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg'] 4 5const ary2: StrAry[] = ary.reduce((t: StrAry[], str: string, i: number) => 6 i % 2 ? [...t.slice(0, t.length-1), [t[t.length-1][0], str]] : [...t, [str]] 7, []) 8 9console.log(ary2)

コード例 3

上記のコード例 2 で、reduce で一度にやろうとしていることを、map と filter の二段階を踏むコードです。

typescript

1type StrAry = string[] 2 3const ary: StrAry = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg'] 4 5const ary2: StrAry[] = ary.map((str: string, i: number, self: StrAry) => 6 i % 2 ? null : (i+1 < self.length ? [str, self[i+1]] : [str]) 7 ).filter((a: StrAry | null) => a) 8 9console.log(ary2) 10 11

コード例 4

これまでの3つとは異なり、文字列を経由した方法です。joinで要素を # で結合した文字列を作り、正規表現によるreplaceによって、一組になる要素を区切る #_ に置換してから、 split, map で、望む配列にするコードです。

typescript

1type StrAry = string[] 2 3const ary: StrAry = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg'] 4 5const ary2: StrAry[] = ary.join('#') 6                 .replace(/([^#]+)#([^#]+)/g, '$1_$2') 7 .split('#') 8 .map((s: string) => s.split('_')) 9 10console.log(ary2) 11

コード例 5

配列やオブジェクトの操作で便利なライブラリlodash の _.chunk を使うと、以下でできます。

typescript

1type StrAry = string[] 2 3const ary: StrAry = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg'] 4 5const ary2: StrAry[] = _.chunk(ary, 2) 6 7console.log(ary2)

コード例 6

上記のコード例 5 で使った、lodash の _.chunk と同様の関数myChunkを(再帰を使って、)自作しました。

typescript

1type StrAry = string[] 2 3const myChunk = (a: StrAry, n: number) => (a.length > 0 ? [a.slice(0, n), ...myChunk(a.slice(n), n)] : []) 4 5const ary: StrAry = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg'] 6 7const ary2: StrAry[] = myChunk(ary, 2) 8console.log(ary2) 9 10const ary3: StrAry[] = myChunk(ary, 3) 11console.log(ary3) 12 13const ary4: StrAry[] = myChunk(ary, 4) 14console.log(ary4) 15 16const ary7: StrAry[] = myChunk(ary, 7) 17console.log(ary7)

以上、参考になれば幸いです。

投稿2019/10/14 12:42

編集2019/10/14 22:27
jun68ykt

総合スコア9058

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

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

yuki_90453

2019/10/15 04:20

ご丁寧な回答ありがとうございます。 参考にさせて頂きます! 無事、解決出来そうです。ありがとうございます。
jun68ykt

2019/10/15 05:19

どういたしまして。 > 無事、解決出来そうです。 とのことで、よかったです ????
guest

0

うーん・・。

TypeScript

1const sku_list_per_limit: string[][] = sku_list.reduce((x: string[][], y: string): string[][] => { 2 if (x.length === 0 || x[x.length - 1].length === 2) { 3 x.push([y]); 4 } else { 5 x[x.length - 1].push(y); 6 } 7 return x; 8}, []);

「逆向きがシンプル」というのなら、分かります。

TypeScript

1const sku_list_2 = sku_list_per_limit.reduce((x: string[], y: string[]): string[] => { 2 return x.concat(y); 3});

投稿2019/10/14 13:00

tanishi_a

総合スコア484

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問