1
+ Array . prototype . copyWithin = copyWithin
2
+
3
+ /**
4
+ * @param {number } target // is where it will be trade by copied value
5
+ * @param {number } start // position that will start to copy items
6
+ * @param {number | undefined } end // position that will end to copy items
7
+ */
8
+ function copyWithin ( target , start = 0 , end = this . length ) {
9
+ if ( target > this . length - 1 || this . length - target < 0 ) {
10
+ throw new Error ( 'Target value is invalid' )
11
+ }
12
+
13
+ const array = this
14
+ let copiedValues = [ ]
15
+
16
+ // Test Passed ><><><><
17
+ if ( start >= 0 && end >= 0 ) {
18
+ if ( start === end ) return array
19
+
20
+ if ( start > end ) {
21
+ for ( let i = end + 1 ; i <= start ; i ++ ) {
22
+ copiedValues . push ( array [ i ] )
23
+ }
24
+ }
25
+
26
+ if ( start < end ) {
27
+ for ( let i = start ; i < end ; i ++ ) {
28
+ copiedValues . push ( array [ i ] )
29
+ }
30
+ }
31
+ }
32
+
33
+ if ( start < 0 && end < 0 ) {
34
+ if ( start === end ) return array
35
+
36
+ if ( start > end ) {
37
+ for ( let i = array . length + end ; i < array . length + start ; i ++ ) {
38
+ copiedValues . push ( array [ i ] )
39
+ }
40
+ }
41
+
42
+ if ( start < end ) {
43
+ for ( let i = array . length + start ; i <= array . length + end - 1 ; i ++ ) {
44
+ copiedValues . push ( array [ i ] )
45
+ }
46
+ }
47
+ }
48
+
49
+ if ( start < 0 && end >= 0 ) {
50
+ if ( end >= array . length || array . length + start < 0 ) return array
51
+ if ( array . length + start === end ) return array
52
+
53
+ if ( array . length + start > end ) {
54
+ for ( let i = end + 1 ; i <= array . length + start ; i ++ ) {
55
+ copiedValues . push ( array [ i ] )
56
+ }
57
+ }
58
+
59
+ if ( array . length + start < end ) {
60
+ for ( let i = array . length + start ; i <= end - 1 ; i ++ ) {
61
+ copiedValues . push ( array [ i ] )
62
+ }
63
+ }
64
+ }
65
+
66
+ if ( start >= 0 && end < 0 ) {
67
+ if ( start >= array . length || array . length + end < 0 ) return array
68
+ if ( array . length + end === start ) return array
69
+
70
+ if ( array . length + end === start ) {
71
+ copiedValues . push ( array [ start ] )
72
+ }
73
+
74
+ if ( array . length + end > start ) {
75
+ for ( let i = start ; i < array . length + end ; i ++ ) {
76
+ copiedValues . push ( array [ i ] )
77
+ }
78
+ }
79
+
80
+ if ( array . length + end < start ) {
81
+ for ( let i = array . length + end + 1 ; i <= start ; i ++ ) {
82
+ copiedValues . push ( array [ i ] )
83
+ }
84
+ }
85
+ }
86
+
87
+ if ( target === 0 ) {
88
+ let counter = copiedValues . length
89
+
90
+ while ( counter > 0 ) {
91
+ counter --
92
+ array . shift ( )
93
+ }
94
+ for ( let i = copiedValues . length - 1 ; i > - 1 ; i -- ) {
95
+ array . unshift ( copiedValues [ i ] )
96
+ }
97
+
98
+ return array
99
+ }
100
+
101
+ if ( target === array . length - 1 || target === - 1 ) {
102
+ array . pop ( )
103
+ array . push ( copiedValues [ 0 ] )
104
+
105
+ return array
106
+ }
107
+
108
+ if ( target !== 0 && array . length + target >= 0 && target !== array . length - 1 && target !== - 1 ) {
109
+ if ( target < 0 ) {
110
+ let targetPosition = array . length
111
+
112
+ while ( target < 0 ) {
113
+ target ++
114
+ targetPosition --
115
+ }
116
+
117
+ const removedItems = array . splice ( targetPosition , copiedValues . length )
118
+
119
+ if ( array . length + removedItems . length - targetPosition > copiedValues . length ) {
120
+ let itemsToInsert = [ ] ;
121
+ copiedValues . forEach ( el => {
122
+ if ( itemsToInsert . length === removedItems . length ) return
123
+ itemsToInsert . push ( el )
124
+ } )
125
+ array . splice ( targetPosition , undefined , ...itemsToInsert )
126
+ }
127
+
128
+ if ( array . length + removedItems . length - targetPosition < copiedValues . length ) {
129
+ while ( array . length + removedItems . length - targetPosition < copiedValues . length ) {
130
+ copiedValues . pop ( )
131
+ }
132
+ array . splice ( targetPosition , undefined , ...copiedValues )
133
+ }
134
+ }
135
+
136
+ if ( target > 0 ) {
137
+ const removedItems = array . splice ( target , copiedValues . length )
138
+
139
+ if ( array . length + removedItems . length + target > copiedValues . length ) {
140
+ let itemsToInsert = [ ] ;
141
+ copiedValues . forEach ( el => {
142
+ if ( itemsToInsert . length === removedItems . length ) return
143
+ itemsToInsert . push ( el )
144
+ } )
145
+ array . splice ( target , undefined , ...itemsToInsert )
146
+ }
147
+
148
+ if ( array . length + removedItems . length + target < copiedValues . length ) {
149
+ while ( array . length + removedItems . length + target < copiedValues . length ) {
150
+ copiedValues . pop ( )
151
+ }
152
+ array . splice ( target , undefined , ...copiedValues )
153
+ }
154
+ }
155
+
156
+ return array
157
+ }
158
+ }
159
+
160
+ module . exports = { copyWithin }
0 commit comments