VList: Difference between revisions

896 bytes added ,  1 year ago
J: bugfix and a caution
(J: bugfix and a caution)
Line 1,004:
 
off=: 0
lastsz=: 01
(current=: 'b1')=: 0
 
size=: {{ 0>.lastsz+off-1 }}
 
get=: {{
assert. y>:0 ['negative index not supported'
assert. i y<size off ['index too large'
bi=. #:y+1
bi=. #:y+1 NB. work with binary representation of origin 1 index
b=. #.(#bi){.1
b=. #.(#bi){.1 NB. most significant bit (the reason for origin 1)
i=. #.}.bi
i=. #.}.bi NB. rest of index
c=.i{do 'b',":b
if. c-:current do.
assert. i < off ['index too large'
end.
i{do c
}}"0
 
unshift=: {{
(current)=: y off} do current
off=: 1+off
if. off=lastsz do.
off=: 0
lastsz=: 1>.2*lastsz
current=: 'b',":lastsz
(current)=: lastsz#0
end.
(current)=: y off} do current
off=: 1+off
y
}}"0
 
shift=: {{
assert. 0<lastsz[size 'vlist empty'
off=: off-1
r=. off{do current
if. 0>off do.
erase current
lastsz=: <.-:lastsz
off=: lastsz-1
current=: 'b',":lastsz
r
end.
ifr=. c-:off{do current do.
}}</lang>
 
Line 1,061 ⟶ 1,059:
size__L''
4</lang>
 
Caution: this is an accurate model of the vlist data structure but should not be used if performance is critical.
 
If performance is critical use J's native operations and make sure that there's only the named reference to the list when adding or removing the last item from the list. For example, given <code>L=:100 200 303 404</code>, use <code>L=: L,555</code> to append to the list, and and after using <code>{:L</code> to extract the final element from L, use <code>L=: }:L</code> to discard the final element from the list. (And, of course, <code>#L</code> will report the size of the list.) J's implementation uses techniques which are in some ways similar in character to vlists for these operations (but uses copy on write if the there's other references to the list).
 
=={{header|Kotlin}}==
6,951

edits