0
# Array Utilities
1
2
Utility functions for reordering arrays after sort operations. Note that `arrayMove` is deprecated in react-sortable-hoc v2.0.0 and users should install the separate `array-move` package instead.
3
4
## Capabilities
5
6
### arrayMove Function (Deprecated)
7
8
Reorders array elements by moving an item from one index to another.
9
10
```typescript { .api }
11
/**
12
* Utility function to reorder array items (DEPRECATED)
13
* @param array - Array to reorder
14
* @param from - Source index
15
* @param to - Target index
16
* @returns New array with moved item
17
* @deprecated Use the 'array-move' package instead
18
*/
19
function arrayMove<T>(
20
array: T[],
21
from: number,
22
to: number
23
): T[];
24
```
25
26
**⚠️ Deprecation Warning**: This function will be removed in the next major release. Install the `array-move` package separately:
27
28
```bash
29
npm install array-move
30
```
31
32
**Usage Examples:**
33
34
```typescript
35
import { arrayMove } from 'react-sortable-hoc'; // Deprecated
36
// OR (recommended)
37
import { arrayMove } from 'array-move';
38
39
// Basic array reordering
40
const items = ['A', 'B', 'C', 'D', 'E'];
41
const reordered = arrayMove(items, 1, 3); // Move 'B' to position 3
42
// Result: ['A', 'C', 'D', 'B', 'E']
43
44
// Move to beginning
45
const toStart = arrayMove(items, 3, 0); // Move 'D' to start
46
// Result: ['D', 'A', 'B', 'C', 'E']
47
48
// Move to end
49
const toEnd = arrayMove(items, 0, -1); // Move 'A' to end
50
// Result: ['B', 'C', 'D', 'E', 'A']
51
```
52
53
### Integration with SortableContainer
54
55
The primary use case is handling the `onSortEnd` callback:
56
57
```typescript
58
import React, { useState } from 'react';
59
import { SortableContainer, SortableElement } from 'react-sortable-hoc';
60
import { arrayMove } from 'array-move'; // Recommended
61
62
const SortableItem = SortableElement(({ value }) => <li>{value}</li>);
63
64
const SortableList = SortableContainer(({ items }) => (
65
<ul>
66
{items.map((value, index) => (
67
<SortableItem key={`item-${index}`} index={index} value={value} />
68
))}
69
</ul>
70
));
71
72
const App = () => {
73
const [items, setItems] = useState(['Item 1', 'Item 2', 'Item 3']);
74
75
const onSortEnd = ({ oldIndex, newIndex }) => {
76
setItems(arrayMove(items, oldIndex, newIndex));
77
};
78
79
return <SortableList items={items} onSortEnd={onSortEnd} />;
80
};
81
```
82
83
### Advanced Array Operations
84
85
#### Moving Multiple Items
86
87
For moving multiple selected items:
88
89
```typescript
90
const moveMultipleItems = (array: any[], selectedIndices: number[], targetIndex: number) => {
91
const selectedItems = selectedIndices.map(index => array[index]);
92
const remainingItems = array.filter((_, index) => !selectedIndices.includes(index));
93
94
// Insert selected items at target position
95
const result = [...remainingItems];
96
result.splice(targetIndex, 0, ...selectedItems);
97
98
return result;
99
};
100
101
// Usage
102
const items = ['A', 'B', 'C', 'D', 'E'];
103
const moved = moveMultipleItems(items, [1, 3], 0); // Move 'B' and 'D' to start
104
// Result: ['B', 'D', 'A', 'C', 'E']
105
```
106
107
#### Conditional Array Moves
108
109
Only move items when conditions are met:
110
111
```typescript
112
const conditionalMove = (
113
array: any[],
114
oldIndex: number,
115
newIndex: number,
116
condition: (item: any) => boolean
117
) => {
118
const item = array[oldIndex];
119
120
if (!condition(item)) {
121
return array; // No change if condition fails
122
}
123
124
return arrayMove(array, oldIndex, newIndex);
125
};
126
127
// Usage
128
const onSortEnd = ({ oldIndex, newIndex }) => {
129
setItems(prevItems =>
130
conditionalMove(
131
prevItems,
132
oldIndex,
133
newIndex,
134
item => !item.locked // Only move unlocked items
135
)
136
);
137
};
138
```
139
140
#### Array Move with Collections
141
142
When working with multiple collections:
143
144
```typescript
145
const moveWithinCollection = (
146
items: any[],
147
oldIndex: number,
148
newIndex: number,
149
collection: string
150
) => {
151
// Filter items by collection
152
const collectionItems = items.filter(item => item.collection === collection);
153
const otherItems = items.filter(item => item.collection !== collection);
154
155
// Move within collection
156
const reorderedCollection = arrayMove(collectionItems, oldIndex, newIndex);
157
158
// Merge back
159
return [...otherItems, ...reorderedCollection];
160
};
161
162
const onSortEnd = ({ oldIndex, newIndex, collection }) => {
163
setItems(prevItems =>
164
moveWithinCollection(prevItems, oldIndex, newIndex, collection)
165
);
166
};
167
```
168
169
### Array Move Alternatives
170
171
#### Using Array.splice()
172
173
Manual implementation without external dependency:
174
175
```typescript
176
const manualArrayMove = <T>(array: T[], fromIndex: number, toIndex: number): T[] => {
177
const result = array.slice(); // Create copy
178
const [removed] = result.splice(fromIndex, 1); // Remove item
179
result.splice(toIndex, 0, removed); // Insert at new position
180
return result;
181
};
182
```
183
184
#### Using Immutable Updates
185
186
For immutable state management:
187
188
```typescript
189
import { produce } from 'immer';
190
191
const immerArrayMove = produce((draft, fromIndex, toIndex) => {
192
const [removed] = draft.splice(fromIndex, 1);
193
draft.splice(toIndex, 0, removed);
194
});
195
196
// Usage
197
const onSortEnd = ({ oldIndex, newIndex }) => {
198
setItems(prevItems => immerArrayMove(prevItems, oldIndex, newIndex));
199
};
200
```
201
202
### Performance Considerations
203
204
#### Large Arrays
205
206
For large arrays, consider using keys based on item IDs rather than indices:
207
208
```typescript
209
const SortableItem = SortableElement(({ item }) => <li>{item.name}</li>);
210
211
const SortableList = SortableContainer(({ items }) => (
212
<ul>
213
{items.map((item, index) => (
214
<SortableItem
215
key={item.id} // Use stable ID, not index
216
index={index}
217
item={item}
218
/>
219
))}
220
</ul>
221
));
222
```
223
224
#### Memoization
225
226
Memoize expensive array operations:
227
228
```typescript
229
import { useMemo } from 'react';
230
231
const App = () => {
232
const [items, setItems] = useState(largeItemList);
233
234
const sortedItems = useMemo(() => {
235
return items.sort((a, b) => a.priority - b.priority);
236
}, [items]);
237
238
const onSortEnd = ({ oldIndex, newIndex }) => {
239
setItems(prevItems => arrayMove(prevItems, oldIndex, newIndex));
240
};
241
242
return <SortableList items={sortedItems} onSortEnd={onSortEnd} />;
243
};
244
```
245
246
### Migration Guide
247
248
#### From react-sortable-hoc arrayMove
249
250
```typescript
251
// Old (deprecated)
252
import { arrayMove } from 'react-sortable-hoc';
253
254
// New (recommended)
255
import { arrayMove } from 'array-move';
256
257
// The API is identical, just change the import
258
const reordered = arrayMove(items, oldIndex, newIndex);
259
```
260
261
#### Installation
262
263
```bash
264
# Install the separate package
265
npm install array-move
266
267
# TypeScript types are included
268
# No need for @types/array-move
269
```
270
271
#### Additional Features
272
273
The standalone `array-move` package provides additional utilities:
274
275
```typescript
276
import { arrayMove, arrayMoveImmutable, arrayMoveMutable } from 'array-move';
277
278
// Immutable (returns new array)
279
const newArray = arrayMoveImmutable([1, 2, 3], 0, 2);
280
281
// Mutable (modifies original array)
282
arrayMoveMutable(originalArray, 0, 2);
283
284
// Standard (same as arrayMoveImmutable)
285
const moved = arrayMove([1, 2, 3], 0, 2);
286
```