Skip to content

Commit 0a17322

Browse files
committed
perf: ⚡️ core array move method optimize, move to shared
1 parent 1e49061 commit 0a17322

File tree

4 files changed

+69
-12
lines changed

4 files changed

+69
-12
lines changed

packages/core/src/__tests__/array.spec.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -297,23 +297,24 @@ test('fault tolerance', () => {
297297
array.move(0, 1)
298298
expect(array.value).toEqual([1])
299299
array.moveUp(1)
300-
expect(array.value).toEqual([undefined, 1])
300+
expect(array.value).toEqual([1])
301301
array.moveDown(1)
302-
expect(array.value).toEqual([1, undefined])
302+
expect(array.value).toEqual([1])
303303
array.insert(1)
304-
expect(array.value).toEqual([1, undefined])
304+
expect(array.value).toEqual([1])
305305
array2.move(1, 1)
306306
expect(array2.value).toEqual([1, 2])
307+
array2.push(3)
307308
array2.moveUp(2)
308-
expect(array2.value).toEqual([1, undefined, 2])
309+
expect(array2.value).toEqual([1, 3, 2])
309310
array2.moveUp(0)
310-
expect(array2.value).toEqual([undefined, 2, 1])
311+
expect(array2.value).toEqual([3, 2, 1])
311312
array2.moveDown(0)
312-
expect(array2.value).toEqual([2, undefined, 1])
313+
expect(array2.value).toEqual([2, 3, 1])
313314
array2.moveDown(1)
314-
expect(array2.value).toEqual([2, 1, undefined])
315+
expect(array2.value).toEqual([2, 1, 3])
315316
array2.moveDown(2)
316-
expect(array2.value).toEqual([undefined, 2, 1])
317+
expect(array2.value).toEqual([3, 2, 1])
317318
})
318319

319320
test('mutation fault tolerance', () => {

packages/core/src/models/ArrayField.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isArr } from '@formily/shared'
1+
import { isArr, move } from '@formily/shared'
22
import { action, reaction } from '@formily/reactive'
33
import {
44
spliceArrayState,
@@ -68,6 +68,9 @@ export class ArrayField<
6868
if (!isArr(this.value)) {
6969
this.value = []
7070
}
71+
if (items.length === 0) {
72+
return
73+
}
7174
spliceArrayState(this, {
7275
startIndex: index,
7376
insertCount: items.length,
@@ -115,9 +118,7 @@ export class ArrayField<
115118
if (!isArr(this.value)) return
116119
if (fromIndex === toIndex) return
117120
return action(() => {
118-
const fromItem = this.value[fromIndex]
119-
this.value.splice(fromIndex, 1)
120-
this.value.splice(toIndex, 0, fromItem)
121+
move(this.value, fromIndex, toIndex)
121122
exchangeArrayState(this, {
122123
fromIndex,
123124
toIndex,

packages/shared/src/__tests__/index.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { isEqual } from '../compare'
44
import {
55
toArr,
66
every,
7+
move,
78
some,
89
findIndex,
910
find,
@@ -958,3 +959,25 @@ test('applyMiddleware with error', async () => {
958959
expect(e).toEqual('this is error')
959960
}
960961
})
962+
963+
test('move', () => {
964+
const array1 = [1]
965+
move(array1, 1, 0)
966+
expect(array1).toEqual([1])
967+
move(array1, 0, 1)
968+
expect(array1).toEqual([1])
969+
move(array1, -1, 1)
970+
expect(array1).toEqual([1])
971+
move(array1, 0, 3)
972+
expect(array1).toEqual([1])
973+
974+
const array2 = [0, 1, 2]
975+
move(array2, 0, 2)
976+
expect(array2).toEqual([1, 2, 0])
977+
move(array2, 1, 1)
978+
expect(array2).toEqual([1, 2, 0])
979+
980+
const array3 = [0, 1, 2, 3]
981+
move(array3, 3, 1)
982+
expect(array3).toEqual([0, 3, 1, 2])
983+
})

packages/shared/src/array.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,3 +279,35 @@ export function includes(val: any, searchElement: any, revert?: boolean) {
279279
if (isStr(val)) return val.includes(searchElement)
280280
return some(val, (item) => item === searchElement, revert)
281281
}
282+
283+
export function move<T extends any>(
284+
array: T[],
285+
fromIndex: number,
286+
toIndex: number
287+
) {
288+
if (fromIndex === toIndex) return array
289+
290+
if (
291+
toIndex < 0 ||
292+
fromIndex < 0 ||
293+
toIndex > array.length - 1 ||
294+
fromIndex > array.length - 1
295+
) {
296+
return array
297+
}
298+
299+
if (fromIndex < toIndex) {
300+
const fromItem = array[fromIndex]
301+
for (let index = fromIndex; index < toIndex; index++) {
302+
array[index] = array[index + 1]
303+
}
304+
array[toIndex] = fromItem
305+
} else {
306+
const fromItem = array[fromIndex]
307+
for (let index = fromIndex; index > toIndex; index--) {
308+
array[index] = array[index - 1]
309+
}
310+
array[toIndex] = fromItem
311+
}
312+
return array
313+
}

0 commit comments

Comments
 (0)