Category talk:Wren-seq: Difference between revisions

Content added Content deleted
(→‎Source code: Lst.indicesOf should return a list of 3 arguments, not 2.)
(→‎Source code: Changes to make this module more consistent with other Wren modules.)
Line 48: Line 48:
// Private helper method to check that 'a' is a list and throw an error otherwise.
// Private helper method to check that 'a' is a list and throw an error otherwise.
static isList_(a) { (a is List) ? true : Fiber.abort("Argument must be a list.") }
static isList_(a) { (a is List) ? true : Fiber.abort("Argument must be a list.") }

// Private helper method to check whether a start index is valid.
static checkStart_(a, start) {
if (start.type != Num || !start.isInteger) Fiber.abort("Start must be an integer.")
var c = a.count
if (start >= c || start < -c) Fiber.abort("Start is out of bounds.")
}


// Searches an unsorted list linearly for a particular value from a start index.
// Searches an unsorted list linearly for a particular value from a start index.
// If the start index is negative, the list is searched in reverse order.
// If the start index is negative, it counts backwards from the end of the list.
// Returns a list of three items:
// Returns a list of three items:
// The first item is a Bool indicating whether the value was found.
// The first item is a Bool indicating whether the value was found.
Line 57: Line 64:
static indicesOf(a, value, start) {
static indicesOf(a, value, start) {
isList_(a)
isList_(a)
checkStart_(a, start)
var count = a.count
var count = a.count
var indices = []
var indices = []
if (count == 0) return [false, 0, indices]
if (count == 0) return [false, 0, indices]
if (start >= 0) {
if (start < 0) start = count + start
if (start >= count) return [false, 0, indices]
for (i in start...count) {
for (i in start...count) {
if (a[i] == value) indices.add(i)
if (a[i] == value) indices.add(i)
}
} else {
start = count + start
if (start < 0) return [false, 0, indices]
for (i in start..0) {
if (a[i] == value) indices.add(i)
}
}
}
if (indices.isEmpty) return [false, 0, indices]
if (indices.isEmpty) return [false, 0, indices]
Line 80: Line 80:
static indexOf(a, value, start) {
static indexOf(a, value, start) {
isList_(a)
isList_(a)
checkStart_(a, start)
return indexOf_(a, value, start)
}

// Private helper method for 'indexOf' which avoids type and bounds checks.
static indexOf_(a, value, start) {
var count = a.count
var count = a.count
if (count == 0) return -1
if (count == 0) return -1
if (start >= 0) {
if (start < 0) start = count + start
if (start >= count) return -1
for (i in start...count) {
for (i in start...count) {
if (a[i] == value) return i
if (a[i] == value) return i
}
} else {
start = count + start
if (start < 0) return -1
for (i in start..0) {
if (a[i] == value) return i
}
}
}
return -1
return -1
}
}

// Returns the index of the last occurrence of 'value' in 'a' or -1 if no matches.
static lastIndexOf(a, value) {
if (a.count == 0) return 0
for (i in a.count-1..0) {
if (a[i] == value) return i
}
return -1
}


// Works similarly to 'indexOf' but returns the index of the first match
// Works similarly to 'indexOf' but returns the index of the first match
// of ANY of a sequence of values or -1 if none of them matched.
// of ANY of a sequence of values or -1 if none of them matched.
static indexOfAny(a, values, start) {
static indexOfAny(a, values, start) {
isList_(a)
checkStart_(a, start)
var i
var i
for (value in values) {
for (value in values) {
if ((i = indexOf(a, value, start)) >= 0) return i
if ((i = indexOf_(a, value, start)) >= 0) return i
}
}
return -1
return -1