Category talk:Wren-seq: Difference between revisions
Content added Content deleted
(→Source code: Added 'replaceAll and 'toMap' methods to Lst class.) |
(→Source code: Added insertAll, clearPart and truncate methods to Lst lass.) |
||
Line 181: | Line 181: | ||
var c = a.count |
var c = a.count |
||
if (start >= c || start < -c) Fiber.abort("Start is out of bounds.") |
if (start >= c || start < -c) Fiber.abort("Start is out of bounds.") |
||
} |
|||
// Inserts all elements of a sequence 'other' into 'a' starting at index 'index'. |
|||
static insertAll(a, other, index) { |
|||
isList_(a) |
|||
checkStart_(a, index) |
|||
if (index < 0) index = index + a.count |
|||
for (e in other) { |
|||
a.insert(index, e) |
|||
index = index + 1 |
|||
} |
|||
return other |
|||
} |
} |
||
Line 458: | Line 470: | ||
} |
} |
||
return found ? value : null |
return found ? value : null |
||
} |
|||
// Removes all elements of 'a' between indices 'start' and 'end' inclusive. |
|||
static clearPart(a, start, end) { |
|||
isList_(a) |
|||
if (a.isEmpty) return |
|||
checkStart_(a, start) |
|||
checkStart_(a, end) |
|||
if (start < 0) start = start + a.count |
|||
if (end < 0) end = end + a.count |
|||
if (end < start) Fiber.abort("'end' cannot be less than 'start'.") |
|||
for (i in end..start) a.removeAt(i) |
|||
} |
|||
// Removes all elements of 'a' from index 'start' to the end. |
|||
static truncate(a, start) { |
|||
clearPart(a, start, -1) |
|||
} |
} |
||
Line 645: | Line 674: | ||
However, unlike a slice, it does not create a new list but references the existing one |
However, unlike a slice, it does not create a new list but references the existing one |
||
which saves memory and reduces pressure on the garbage collector. |
which saves memory and reduces pressure on the garbage collector. |
||
Indexing of the view always starts at 0, and setting/swapping/sorting elements of |
Indexing of the view always starts at 0, and setting/swapping/sorting elements of |
||
of the view will be reflected in the underlying list and vice versa. However, deletions |
of the view will be reflected in the underlying list and vice versa. However, deletions |
||
from the underlying list may invalidate the view bounds and insertions may 'move' it. |
from the underlying list may invalidate the view bounds and insertions may 'move' it. |
||
As in the case of the List class, views support negative indices. |
As in the case of the List class, views support negative indices. |
||
There is inevitably a performance penalty when indexing the elements of the View compared |
There is inevitably a performance penalty when indexing the elements of the View compared |
||
to indexing the elements of the underlying list directly. To mitigate this penalty, |
to indexing the elements of the underlying list directly. To mitigate this penalty, |
||
Line 677: | Line 706: | ||
_count = end - start + 1 |
_count = end - start + 1 |
||
} |
} |
||
// Private constructor which does not check the arguments. |
// Private constructor which does not check the arguments. |
||
construct new_(lst, start, end) { |
construct new_(lst, start, end) { |
||
Line 685: | Line 714: | ||
_count = end - start + 1 |
_count = end - start + 1 |
||
} |
} |
||
// Self-evident properties |
// Self-evident properties |
||
primary { _lst } |
primary { _lst } |
||
Line 691: | Line 720: | ||
end { _end } |
end { _end } |
||
count { _count } |
count { _count } |
||
// Converts the view to a new independent list. |
// Converts the view to a new independent list. |
||
toList { _lst[_start.._end] } |
toList { _lst[_start.._end] } |
||
// Gets or sets the value at index 'i' of the view (zero based). |
// Gets or sets the value at index 'i' of the view (zero based). |
||
[i] { |
[i] { |
||
Line 701: | Line 730: | ||
return _lst[i + _start] |
return _lst[i + _start] |
||
} |
} |
||
[i]=(v) { |
[i]=(v) { |
||
if (i < 0) i = _count + i |
if (i < 0) i = _count + i |
||
Line 707: | Line 736: | ||
_lst[i + _start] = v |
_lst[i + _start] = v |
||
} |
} |
||
// Unsafe versions of the above indexers which are much quicker as the index is |
// Unsafe versions of the above indexers which are much quicker as the index is |
||
// not adjusted if negative nor checked to be within the view's bounds before |
// not adjusted if negative nor checked to be within the view's bounds before |
||
Line 713: | Line 742: | ||
// Only use when certain this adjustment/check is unnecessary. |
// Only use when certain this adjustment/check is unnecessary. |
||
get(i) { _lst[i + _start] } |
get(i) { _lst[i + _start] } |
||
set(i, v) { |
set(i, v) { |
||
_lst[i + _start] = v |
_lst[i + _start] = v |
||
} |
} |
||
// Returns a new View which is a slice of this one. |
// Returns a new View which is a slice of this one. |
||
slice(start, end) { |
slice(start, end) { |
||
Line 726: | Line 755: | ||
return View.new_(_lst, start + _start, end + _start) |
return View.new_(_lst, start + _start, end + _start) |
||
} |
} |
||
// Copies this to a new otherwise identical View. |
// Copies this to a new otherwise identical View. |
||
copy() { View.new_(_lst, _start, _end) } |
copy() { View.new_(_lst, _start, _end) } |
||
// Returns the index of 'v' in the view or -1 if it does not exist. |
// Returns the index of 'v' in the view or -1 if it does not exist. |
||
indexOf(v) { |
indexOf(v) { |
||
Line 737: | Line 766: | ||
return -1 |
return -1 |
||
} |
} |
||
// Returns the last index of 'v' in the view or -1 if it does not exist. |
// Returns the last index of 'v' in the view or -1 if it does not exist. |
||
lastIndexOf(v) { |
lastIndexOf(v) { |
||
Line 745: | Line 774: | ||
return -1 |
return -1 |
||
} |
} |
||
// Returns whether or not the view contains the value 'v' |
// Returns whether or not the view contains the value 'v' |
||
contains(v) { indexOf(v) >= 0 } |
contains(v) { indexOf(v) >= 0 } |
||
// Swaps the elements at indices 'i' and 'j' in the view. |
// Swaps the elements at indices 'i' and 'j' in the view. |
||
swap(i, j) { |
swap(i, j) { |
||
Line 757: | Line 786: | ||
_lst.swap(i + _start, j + _start) |
_lst.swap(i + _start, j + _start) |
||
} |
} |
||
// Unsafe version of 'swap' above which is much quicker as the indices are |
// Unsafe version of 'swap' above which is much quicker as the indices are |
||
// not adjusted if negative nor checked to be within the view's bounds before |
// not adjusted if negative nor checked to be within the view's bounds before |
||
Line 765: | Line 794: | ||
_lst.swap(i + _start, j + _start) |
_lst.swap(i + _start, j + _start) |
||
} |
} |
||
// Sorts the elements of the view in place using 'comparer' and returns it. |
// Sorts the elements of the view in place using 'comparer' and returns it. |
||
sort(comparer) { |
sort(comparer) { |
||
Line 771: | Line 800: | ||
return this |
return this |
||
} |
} |
||
// Sorts the elements of the view in place using the default comparer and returns it. |
// Sorts the elements of the view in place using the default comparer and returns it. |
||
sort() { |
sort() { |
||
Line 777: | Line 806: | ||
return this |
return this |
||
} |
} |
||
// Sets all the elements of the view to the value 'v'. |
// Sets all the elements of the view to the value 'v'. |
||
setAll(v) { |
setAll(v) { |
||
for (i in _start.._end) _lst[i] = v |
for (i in _start.._end) _lst[i] = v |
||
} |
} |
||
// Checks whether the view bounds are still valid following deletions from the underlying list. |
// Checks whether the view bounds are still valid following deletions from the underlying list. |
||
// If false, do not use unless and until the view becomes valid again. |
// If false, do not use unless and until the view becomes valid again. |
||
isValid { _end < _lst.count } |
isValid { _end < _lst.count } |
||
// Iteration protocol methods. Note that the indices returned (although not normally exposed) |
// Iteration protocol methods. Note that the indices returned (although not normally exposed) |
||
// are those into the underlying list not the view itself. |
// are those into the underlying list not the view itself. |
||
Line 797: | Line 826: | ||
return _taken > _count ? null : _lst.iterate(iterator) |
return _taken > _count ? null : _lst.iterate(iterator) |
||
} |
} |
||
iteratorValue(iterator) { _lst.iteratorValue(iterator) } |
iteratorValue(iterator) { _lst.iteratorValue(iterator) } |
||
// Returns the string representation of the view. |
// Returns the string representation of the view. |
||
toString { "[" + _lst.skip(_start).take(_count).join(", ") + "]" } |
toString { "[" + _lst.skip(_start).take(_count).join(", ") + "]" } |