こんにちは
まず、
① reduceメソッドの 戻り値の累積変数の型を指定方法はありますでしょうか?
上記のコードの末尾 [[]]の事です。
については、
javascript
1sku_list.reduce((table, item) => {
の、reduceに与えている関数の引数 table
と item
に型指定を追加して
typescript
1sku_list.reduce((table: string[][], item: string) => {
としてみるといかがでしょうか?次に、
② reduceメソッドを使った方がわかりやすいと聞いて作ってみたのですが、私のコードは非常に見づらくわかりにくいです。わかりやすいように書きたいのですが、ご指摘頂けないでしょうか?
については、以下の6つのコード例を順に挙げます。
- yuki_90453さんがご質問に挙げられているコードに近いもの(reduceを使用)
- 上記 1. の reduceに与える関数の、コード行を減らしたもの
- reduce の替わりに、map と filter を使用する例
- 文字列を経由して、正規表現によるreplaceおよび split, map を使う例
- loadsh の _.chunk を使用した例
- 上記 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/15 04:20
2019/10/15 05:19