Posted at

Slice notation - TC39 Proposals

この記事は2019年10月9日に書いたものであり、#tc39_study TC39 Proposals LT 大会で使用したものです。



状況



提案内容

slice表記構文を追加する提案。

現状はArray.prototype.slice()を使用して、配列から指定した要素を元にして配列をshallow copyする。



  • 左は配列の下限(デフォルト0)

  • 真ん中は配列の上限(デフォルトは配列の長さ)

  • 右はステップ引数、1はなにもない、2は最初と最後の値の配列(デフォルトは1)

  • すべて指定しなくてもOK

const arr = ['a', 'b', 'c', 'd'];

arr[1:4:2];
// → ['b', 'd']


Prior artの章にもあるように、すでにPython、CoffeeScript、Go、Rubyでは同様のことができると説明がある(触ったことがないのでわからない)


slice表記構文を使用する場合はこのようになる

const arr = ['a', 'b', 'c', 'd'];

const str = 'hello world';

arr.slice(1, 3);
// → ['b', 'c']

str.slice(6);
// → 'world'


Slice notationの場合はこうなる.



  • arr[1:3];は2つめから3つめの要素の配列を生成する


  • str[6:];:の右辺を指定していないので、6文字目から先のすべての要素が含まれた配列を生成する


const arr = ['a', 'b', 'c', 'd'];
const str = 'hello world';

arr[1:3];
// → ['b', 'c']

str[6:];
// → 'world'


このようにobjectのindexにアクセスして操作もできる

const obj = { 0: 'a', 1: 'b', 2: 'c', 3: 'd', length: 4 };

obj[1:3];
// → ['b', 'c']


const arr = ['a', 'b', 'c', 'd'];

arr[:3:1]; // 下限引数は指定されていないので0
// → ['a', 'b', 'c']

arr[1::1]; // 上限引数は指定されていないので配列長さである4
// → ['b', 'c', 'd']

arr[1:]; // 上限引数は上記の通り4、ステップ引数は指定されていないので1
// → ['b', 'c', 'd']

arr[:3]; // 上限引数は上記の通り0、ステップ引数は上記の通り1
// → ['a', 'b', 'c']

arr[1::2]; // 上限引数は上記の通り4、ステップ引数は上記の通り2なので、要素の最初と最後を取得
// → ['b', 'd']

arr[:3:2]; // 下限引数は指定されていないので0、ステップ引数は2なので、要素の最初と最後を取得
// → ['a', 'c']


なにも指定しない場合は、配列のshallow copyになる


const arr = ['a', 'b', 'c', 'd'];
arr[:];
// → ['a', 'b', 'c', 'd']

arr[::];
// → ['a', 'b', 'c', 'd']



  • マイナス表記もある

  • 下限計算start = max(lowerBound + len, 0)

  • 上限計算end = max(upperBound + len, 0)

  • 配列の要素を逆転させたい場合はステップ引数を-1にする


const arr = ['a', 'b', 'c', 'd'];

arr[-2:];
// start = max((-2 + 4), 0) = max(2, 0) = 2
// → ['c', 'd']

arr[-10:];
// start = max((-10 + 4), 0) = max(-6, 0) = 0
// → ['a', 'b', 'c', 'd']

arr[:-2];
// end = max((-2 + 4), 0) = max(2, 0) = 2
// → ['a', 'b']

arr[:-10];
// end = max((-10 + 4), 0) = max(-6, 0) = 0
// → []

arr[::-1];
// → ['d', 'c', 'b', 'a']


上限と下限は配列の長さで制限がある


const arr = ['a', 'b', 'c', 'd'];

arr[100:];
// → []

arr[:100];
// → ['a', 'b', 'c', 'd']