-
Notifications
You must be signed in to change notification settings - Fork 0
/
arrayCopy.ts
119 lines (105 loc) · 3.48 KB
/
arrayCopy.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*!
* @author electricessence / https://github.com/electricessence/
* Licensing: MIT
*/
import {ArrayLikeWritable} from '@tsdotnet/common-interfaces';
import arrayInit from '@tsdotnet/array-init';
import ArgumentNullException from '@tsdotnet/exceptions/dist/ArgumentNullException';
import ArgumentOutOfRangeException from '@tsdotnet/exceptions/dist/ArgumentOutOfRangeException';
/* eslint-disable no-inner-declarations */
const
CBN = 'Cannot be null.',
CBL0 = 'Cannot be less than zero.';
/**
* Copies one array to another.
* @param source
* @param destination
* @param sourceIndex
* @param destinationIndex
* @param count An optional limit to stop copying. Finite values must be no more than the source.length minus the sourceIndex.
* @returns The destination array.
*/
export function arrayCopyTo<T, TDestination extends ArrayLikeWritable<T>> (
source: ArrayLike<T>,
destination: TDestination,
sourceIndex: number = 0,
destinationIndex: number = 0,
count: number = Infinity
): TDestination
{
if(!source) throw new ArgumentNullException('source', CBN);
if(!destination) throw new ArgumentNullException('destination', CBN);
if(sourceIndex<0) throw new ArgumentOutOfRangeException('sourceIndex', sourceIndex, CBL0);
if(destinationIndex<0) throw new ArgumentOutOfRangeException('destinationIndex', destinationIndex, CBL0);
const sourceLength = source.length;
if(!sourceLength || count<1) return destination;
if(sourceIndex>=sourceLength)
throw new ArgumentOutOfRangeException(
'sourceIndex',
sourceIndex,
'Must be less than the length of the source array.'
);
// deal with ArrayLike issues.
if(destination.length<0) throw new ArgumentOutOfRangeException('destination.length', destination.length, CBL0);
const max = source.length - sourceIndex;
if(isFinite(count) && count>max)
throw new ArgumentOutOfRangeException(
'sourceIndex',
sourceIndex,
'Source index + length cannot exceed the length of the source array.'
);
count = Math.min(count, max);
const newLength = destinationIndex + count;
if(newLength>destination.length) destination.length = newLength;
for(let i = 0; i<count; i++)
{
destination[destinationIndex + i] = source[sourceIndex + i];
}
return destination;
}
/**
* Creates a copy of the array-like object.
* Similar to Array.slice(index, length).
* @param source
* @param sourceIndex
* @param count An optional limit to stop copying. Finite values must be no more than the source.length minus the sourceIndex.
* @returns The copy of the source array.
*/
function arrayCopy<T> (
source: ArrayLike<T>,
sourceIndex: number = 0,
count: number = Infinity): T[]
{
if(!source) return source as any; // may have passed zero? undefined? or null?
return arrayCopyTo(
source,
arrayInit<T>(Math.min(count, Math.max(source.length - sourceIndex, 0))),
sourceIndex,
0,
count
);
}
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace arrayCopy
{
/**
* Copies one array to another.
* @param source
* @param destination
* @param sourceIndex
* @param destinationIndex
* @param length An optional limit to stop copying.
* @returns The destination array.
*/
export function to<T, TDestination extends ArrayLikeWritable<T>> (
source: ArrayLike<T>,
destination: TDestination,
sourceIndex: number = 0,
destinationIndex: number = 0,
length: number = Infinity
): TDestination
{
return arrayCopyTo(source, destination, sourceIndex, destinationIndex, length);
}
}
export default arrayCopy;