Skip to content

Commit

Permalink
Merge pull request #621 from salano-ym/arr-splice
Browse files Browse the repository at this point in the history
arr.spliceを追加
  • Loading branch information
salano-ym authored May 12, 2024
2 parents c90a098 + 324fddd commit 9e61804
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- `arr.flat`,`arr.flat_map`を追加
- `Uri:encode_full`, `Uri:encode_component`, `Uri:decode_full`, `Uri:decode_component`を追加
- `str.starts_with`,`str.ends_with`を追加
- `arr.splice`を追加

# 0.18.0
- `Core:abort`でプログラムを緊急停止できるように
Expand Down
9 changes: 9 additions & 0 deletions docs/primitive-props.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,15 @@ _fromIndex_ および _toIndex_ に関する挙動は`arr.slice`に準拠しま
`arr.copy`同様シャローコピーであり、配列やオブジェクトの参照は維持されます。
_times_ には0以上の整数値を指定します。それ以外ではエラーになります。

### @(_v_: arr).splice(_index_: num, _remove_count_?: num, _items_?: arr\<value>): arr\<value>
**【この操作は配列を書き換えます】**
配列の _index_ から _remove_count_ 個の要素を取り除き、その位置に _items_ の要素を挿入します。
返り値として、取り除いた要素の配列を返します。\
_index_ が負の場合は末尾から数えます。\
_index_ が最後の要素より後の場合は要素を取り除かず、挿入は末尾に追加します。\
_remove_count_ を省略した場合、末尾まで取り除きます。\
_items_ を省略した場合、何も挿入しません。

### @(_v_: arr).flat(_depth_?: num): arr
配列に含まれる配列を _depth_ で指定した深さの階層まで結合した新しい配列を作成します。
_depth_ には0以上の整数値を指定します。省略時は1になります。
Expand Down
16 changes: 16 additions & 0 deletions src/interpreter/primitive-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,22 @@ const PRIMITIVE_PROPS: {
throw e;
}
}),

splice: (target: VArr): VFn => FN_NATIVE(async ([idx, rc, vs], opts) => {
assertNumber(idx);
const index = (idx.value < -target.value.length) ? 0
: (idx.value < 0) ? target.value.length + idx.value
: (idx.value >= target.value.length) ? target.value.length
: idx.value;

const remove_count = (rc != null) ? (assertNumber(rc), rc.value)
: target.value.length - index;

const items = (vs != null) ? (assertArray(vs), vs.value) : [];

const result = target.value.splice(index, remove_count, ...items);
return ARR(result);
}),

flat: (target: VArr): VFn => FN_NATIVE(async ([depth], opts) => {
depth = depth ?? NUM(1);
Expand Down
48 changes: 48 additions & 0 deletions test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3014,6 +3014,54 @@ describe('primitive props', () => {
ARR([]),
]));
});

test.concurrent('splice (full)', async () => {
const res = await exe(`
let arr1 = [0, 1, 2, 3]
let arr2 = arr1.splice(1, 2, [10])
<: [arr1, arr2]
`);
eq(res, ARR([
ARR([NUM(0), NUM(10), NUM(3)]),
ARR([NUM(1), NUM(2)]),
]));
});

test.concurrent('splice (negative-index)', async () => {
const res = await exe(`
let arr1 = [0, 1, 2, 3]
let arr2 = arr1.splice(-1, 0, [10, 20])
<: [arr1, arr2]
`);
eq(res, ARR([
ARR([NUM(0), NUM(1), NUM(2), NUM(10), NUM(20), NUM(3)]),
ARR([]),
]));
});

test.concurrent('splice (larger-index)', async () => {
const res = await exe(`
let arr1 = [0, 1, 2, 3]
let arr2 = arr1.splice(4, 100, [10, 20])
<: [arr1, arr2]
`);
eq(res, ARR([
ARR([NUM(0), NUM(1), NUM(2), NUM(3), NUM(10), NUM(20)]),
ARR([]),
]));
});

test.concurrent('splice (single argument)', async () => {
const res = await exe(`
let arr1 = [0, 1, 2, 3]
let arr2 = arr1.splice(1)
<: [arr1, arr2]
`);
eq(res, ARR([
ARR([NUM(0)]),
ARR([NUM(1), NUM(2), NUM(3)]),
]));
});

test.concurrent('flat', async () => {
const res = await exe(`
Expand Down

0 comments on commit 9e61804

Please sign in to comment.