@@ -16,53 +16,94 @@ const resolveEnd = (pEnd, length, step) => {
1616 return resolveIndex ( pEnd , length )
1717}
1818
19+ const getRange = ( pStart , pEnd , pStep , value ) => {
20+ const step = pStep === undefined ? 1 : pStep
21+ const length = getLength ( value )
22+ const start = resolveStart ( pStart , length , step )
23+ const end = resolveEnd ( pEnd , length , step )
24+ if ( step > 0 ) {
25+ if ( end <= start ) return null
26+ return {
27+ [ Symbol . iterator ] : ( ) => {
28+ let i = start
29+ return {
30+ next : ( ) => {
31+ if ( i < end ) {
32+ const res = {
33+ value : i ,
34+ done : false ,
35+ }
36+ i += step
37+ return res
38+ }
39+ return { done : true }
40+ } ,
41+ }
42+ } ,
43+ }
44+ }
45+ if ( end >= start ) return null
46+ return {
47+ [ Symbol . iterator ] : ( ) => {
48+ let i = start
49+ return {
50+ next : ( ) => {
51+ if ( i > end ) {
52+ const res = {
53+ value : i ,
54+ done : false ,
55+ }
56+ i += step
57+ return res
58+ }
59+ return { done : true }
60+ } ,
61+ }
62+ } ,
63+ }
64+ }
65+
1966const update = ( [ pStart , pEnd , pStep ] , next ) => updater => {
2067 const nextUpdater = next ( updater )
21- const step = pStep === undefined ? 1 : pStep
2268 return onCopy ( ( newValue , value ) => {
23- const length = getLength ( value )
24- const start = resolveStart ( pStart , length , step )
25- const end = resolveEnd ( pEnd , length , step )
26- if ( step > 0 ) {
27- if ( end <= start ) return // TODO avoid useless copy
28- if ( isNil ( value ) )
29- for ( let i = start ; i < end ; i += step ) newValue [ i ] = nextUpdater ( undefined )
30- else
31- for ( let i = start ; i < end ; i += step ) newValue [ i ] = nextUpdater ( value [ i ] )
32- }
33- if ( end >= start ) return // TODO avoid useless copy
69+ const range = getRange ( pStart , pEnd , pStep , value )
70+ if ( ! range ) return // TODO avoid useless copy
3471 if ( isNil ( value ) )
35- for ( let i = start ; i > end ; i += step ) newValue [ i ] = nextUpdater ( undefined )
72+ for ( const i of range ) newValue [ i ] = nextUpdater ( undefined )
3673 else
37- for ( let i = start ; i > end ; i += step ) newValue [ i ] = nextUpdater ( value [ i ] )
74+ for ( const i of range ) newValue [ i ] = nextUpdater ( value [ i ] )
3875 } , true )
3976}
4077
4178const get = ( [ pStart , pEnd , pStep ] , next ) => ( ) => {
4279 const nextGetter = next ( )
43- const step = pStep === undefined ? 1 : pStep
4480 return value => {
45- const length = getLength ( value )
46- const start = resolveStart ( pStart , length , step )
47- const end = resolveEnd ( pEnd , length , step )
4881 if ( isNil ( value ) ) return [ ]
49- let range
50- if ( step > 0 ) {
51- if ( end <= start ) return [ ]
52- range = ( function * ( ) {
53- for ( let i = start ; i < end ; i += step ) yield i
54- } ( ) )
55- } else {
56- if ( end >= start ) return [ ]
57- range = ( function * ( ) {
58- for ( let i = start ; i > end ; i += step ) yield i
59- } ( ) )
60- }
82+ const range = getRange ( pStart , pEnd , pStep , value )
83+ if ( ! range ) return [ ]
6184 return Array . from ( range , i => nextGetter ( value [ i ] ) )
6285 }
6386}
6487
88+ const unsetSlice = ( pStart , pEnd , pStep , nextUnsetter ) => ( ) => onCopy ( value => {
89+ const range = getRange ( pStart , pEnd , pStep , value )
90+ if ( ! range ) return // TODO avoid useless copy
91+ for ( const i of range ) value [ i ] = nextUnsetter ( value [ i ] )
92+ } )
93+
94+ const deleteSlice = ( pStart , pEnd , pStep ) => ( ) => onCopy ( value => {
95+ const range = getRange ( pStart , pEnd , pStep , value )
96+ if ( ! range ) return // TODO avoid useless copy
97+ for ( const i of range ) delete value [ i ]
98+ } )
99+
100+ const unset = ( [ pStart , pEnd , pStep ] , next ) => {
101+ const nextUnsetter = next ( )
102+ return nextUnsetter ? unsetSlice ( pStart , pEnd , pStep , nextUnsetter ) : deleteSlice ( pStart , pEnd , pStep )
103+ }
104+
65105export const sliceNav = makeNav ( {
66106 update,
67107 get,
108+ unset,
68109} )
0 commit comments