shithub: purgatorio

ref: db1eb844461b07a25ca49117851fa874fd88e065
dir: /appl/lib/arrays.b/

View raw version
implement Arrays;

include "arrays.m";

# Return the array 'a' for which 'f' is fulfilled on its contents
filter[T](a: array of T, p: ref fn(x: T): int): array of T {
	if(a == nil)
		return nil;

	if(p(a[0]))
		return prepend(filter(tail(a), p), a[0]);

	if(len a < 2)
		return nil;

	return filter(tail(a), p);
}

# Return the array 'a₀' with the function 'f' applied to its contents
map[T](a₀: array of T, f: ref fn(x: T): T): array of T {
	if(a₀ == nil)
		return nil;

	a₁ := array[len a₀] of T;

	for(i := 0; i < len a₀; i++)
		a₁[i] = f(a₀[i]);

	return a₁;
}

# Create an array whose contents are the pairs of two equally-sized arrays
pair[T₁, T₂](a₁: array of T₁, a₂: array of T₂): array of (T₁, T₂) {
	if(a₁ == nil || a₂ == nil || len a₁ != len a₂)
		return nil;

	a₃ := array[len a₁] of (T₁, T₂);

	for(i := 0; i < len a₁; i++)
		a₃[i] = (a₁[i], a₂[i]);

	return a₃;
}

# Find instance of 'x' in 'l', return tail of 'l' from and including 'x'
find[T](a: array of T, x: T): array of T
	for {
		T =>	Equals:	fn(a, b: T): int;
	}
{
	for(i := 0; i < len a; i++)
		if(T.Equals(x, a[i]))
			return tail(a[i:]);

	return nil;
}

# Return the array 'a₀' with 'x' prepended
prepend[T](a₀: array of T, x: T): array of T {
	if(a₀ == nil)
		return array[1] of { * => x };

	a₁ := array[len a₀ + 1] of T;
	a₁[0] = x;

	for(i := 1; i < len a₁; i++)
		a₁[i] = a₀[i-1];

	return a₁;
}

# Return the array 'a₀' with 'x' appended
append[T](a₀: array of T, x: T): array of T {
	if(a₀ == nil)
		return array[1] of { * => x };

	a₁ := array[len a₀ + 1] of T;
	a₁[len a₁ - 1] = x;

	for(i := 0; i < len a₁ -1; i++)
		a₁[i] = a₀[i];

	return a₁;
}

# Return 'a[1:]' if possible, or nil
tail[T](a: array of T): array of T {
	if(a == nil || len a < 2)
		return nil;

	return a[1:];
}

# Return a pretty string representing the array
stringify[T](a: array of T): string
	for {
		T =>	String:	fn(a: self T): string;
	}
{
	if(a == nil) {
		return "[]\n";
	}

	s := "[";

	for(i := 0; i < len a; i++) {
		s += a[i].String();

		if(i < len a - 1)
			s += ", ";
	}

	return s + "]\n";
}