Skip to content

Commit 71bebc7

Browse files
committed
Optimize move, removing the need to move field state to a temporary field or looping over fields many times.
1 parent d7c4856 commit 71bebc7

File tree

4 files changed

+36
-107
lines changed

4 files changed

+36
-107
lines changed

src/move.js

+36-28
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
// @flow
22
import type { MutableState, Mutator, Tools } from 'final-form'
3-
import moveFields from './moveFields'
4-
import restoreFunctions from './restoreFunctions'
5-
6-
const TMP: string = 'tmp'
3+
import copyField from './copyField'
4+
import { escapeRegexTokens } from './utils'
75

86
const move: Mutator<any> = (
97
[name, from, to]: any[],
@@ -21,34 +19,44 @@ const move: Mutator<any> = (
2119
return copy
2220
})
2321

24-
//make a copy of a state for further functions restore
25-
const backupState = { ...state, fields: { ...state.fields } }
26-
27-
// move this row to tmp index
28-
const fromPrefix = `${name}[${from}]`
29-
moveFields(name, fromPrefix, TMP, state)
30-
31-
if (from < to) {
32-
// moving to a higher index
33-
// decrement all indices between from and to
34-
for (let i = from + 1; i <= to; i++) {
35-
const innerFromPrefix = `${name}[${i}]`
36-
moveFields(name, innerFromPrefix, `${i - 1}`, state)
37-
}
22+
const newFields = {}
23+
const pattern = new RegExp(`^${escapeRegexTokens(name)}\\[(\\d+)\\](.*)`)
24+
let lowest
25+
let highest
26+
let increment
27+
if (from > to) {
28+
lowest = to
29+
highest = from
30+
increment = 1
3831
} else {
39-
// moving to a lower index
40-
// increment all indices between to and from
41-
for (let i = from - 1; i >= to; i--) {
42-
const innerFromPrefix = `${name}[${i}]`
43-
moveFields(name, innerFromPrefix, `${i + 1}`, state)
44-
}
32+
lowest = from
33+
highest = to
34+
increment = -1
4535
}
36+
Object.keys(state.fields).forEach(key => {
37+
const tokens = pattern.exec(key)
38+
if (tokens) {
39+
const fieldIndex = Number(tokens[1])
40+
if (fieldIndex === from) {
41+
const newKey = `${name}[${to}]${tokens[2]}`
42+
copyField(state.fields, key, newFields, newKey)
43+
return
44+
}
45+
46+
if (lowest <= fieldIndex && fieldIndex <= highest) {
47+
// Shift all indices
48+
const newKey = `${name}[${fieldIndex + increment}]${tokens[2]}`
49+
copyField(state.fields, key, newFields, newKey)
50+
return
51+
}
52+
}
4653

47-
// move from tmp index to destination
48-
const tmpPrefix = `${name}[${TMP}]`
49-
moveFields(name, tmpPrefix, to, state)
54+
// Keep this field that does not match the name,
55+
// or has index smaller or larger than affected range
56+
newFields[key] = state.fields[key]
57+
})
5058

51-
restoreFunctions(state, backupState)
59+
state.fields = newFields
5260
}
5361

5462
export default move

src/moveFieldState.js

-33
This file was deleted.

src/moveFields.js

-20
This file was deleted.

src/restoreFunctions.js

-26
This file was deleted.

0 commit comments

Comments
 (0)