Skip to content

Commit

Permalink
perf: ⚡️ core array move method optimize, move to shared (#3863)
Browse files Browse the repository at this point in the history
  • Loading branch information
charlzyx authored Jun 25, 2023
1 parent 0345e01 commit 3349815
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 12 deletions.
17 changes: 9 additions & 8 deletions packages/core/src/__tests__/array.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,23 +297,24 @@ test('fault tolerance', () => {
array.move(0, 1)
expect(array.value).toEqual([1])
array.moveUp(1)
expect(array.value).toEqual([undefined, 1])
expect(array.value).toEqual([1])
array.moveDown(1)
expect(array.value).toEqual([1, undefined])
expect(array.value).toEqual([1])
array.insert(1)
expect(array.value).toEqual([1, undefined])
expect(array.value).toEqual([1])
array2.move(1, 1)
expect(array2.value).toEqual([1, 2])
array2.push(3)
array2.moveUp(2)
expect(array2.value).toEqual([1, undefined, 2])
expect(array2.value).toEqual([1, 3, 2])
array2.moveUp(0)
expect(array2.value).toEqual([undefined, 2, 1])
expect(array2.value).toEqual([3, 2, 1])
array2.moveDown(0)
expect(array2.value).toEqual([2, undefined, 1])
expect(array2.value).toEqual([2, 3, 1])
array2.moveDown(1)
expect(array2.value).toEqual([2, 1, undefined])
expect(array2.value).toEqual([2, 1, 3])
array2.moveDown(2)
expect(array2.value).toEqual([undefined, 2, 1])
expect(array2.value).toEqual([3, 2, 1])
})

test('mutation fault tolerance', () => {
Expand Down
9 changes: 5 additions & 4 deletions packages/core/src/models/ArrayField.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isArr } from '@formily/shared'
import { isArr, move } from '@formily/shared'
import { action, reaction } from '@formily/reactive'
import {
spliceArrayState,
Expand Down Expand Up @@ -68,6 +68,9 @@ export class ArrayField<
if (!isArr(this.value)) {
this.value = []
}
if (items.length === 0) {
return
}
spliceArrayState(this, {
startIndex: index,
insertCount: items.length,
Expand Down Expand Up @@ -115,9 +118,7 @@ export class ArrayField<
if (!isArr(this.value)) return
if (fromIndex === toIndex) return
return action(() => {
const fromItem = this.value[fromIndex]
this.value.splice(fromIndex, 1)
this.value.splice(toIndex, 0, fromItem)
move(this.value, fromIndex, toIndex)
exchangeArrayState(this, {
fromIndex,
toIndex,
Expand Down
23 changes: 23 additions & 0 deletions packages/shared/src/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { isEqual } from '../compare'
import {
toArr,
every,
move,
some,
findIndex,
find,
Expand Down Expand Up @@ -958,3 +959,25 @@ test('applyMiddleware with error', async () => {
expect(e).toEqual('this is error')
}
})

test('move', () => {
const array1 = [1]
move(array1, 1, 0)
expect(array1).toEqual([1])
move(array1, 0, 1)
expect(array1).toEqual([1])
move(array1, -1, 1)
expect(array1).toEqual([1])
move(array1, 0, 3)
expect(array1).toEqual([1])

const array2 = [0, 1, 2]
move(array2, 0, 2)
expect(array2).toEqual([1, 2, 0])
move(array2, 1, 1)
expect(array2).toEqual([1, 2, 0])

const array3 = [0, 1, 2, 3]
move(array3, 3, 1)
expect(array3).toEqual([0, 3, 1, 2])
})
32 changes: 32 additions & 0 deletions packages/shared/src/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,3 +279,35 @@ export function includes(val: any, searchElement: any, revert?: boolean) {
if (isStr(val)) return val.includes(searchElement)
return some(val, (item) => item === searchElement, revert)
}

export function move<T extends any>(
array: T[],
fromIndex: number,
toIndex: number
) {
if (fromIndex === toIndex) return array

if (
toIndex < 0 ||
fromIndex < 0 ||
toIndex > array.length - 1 ||
fromIndex > array.length - 1
) {
return array
}

if (fromIndex < toIndex) {
const fromItem = array[fromIndex]
for (let index = fromIndex; index < toIndex; index++) {
array[index] = array[index + 1]
}
array[toIndex] = fromItem
} else {
const fromItem = array[fromIndex]
for (let index = fromIndex; index > toIndex; index--) {
array[index] = array[index - 1]
}
array[toIndex] = fromItem
}
return array
}

0 comments on commit 3349815

Please sign in to comment.