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(", ") + "]" }