Slide 20 de 74

Percorrendo e ordenando

map, filter e filterMap
func isLong(fruit: Str): Bool {
	return len(fruit) > 4
}

func shout(fruit: Str): Str {
	return fruit + "!"
}

func evenHalf(n: Int): Result<Int, Bool> {
	if n % 2 == 0 {
		return Result.Ok(n / 2)
	}
	return Result.Error(false)
}

proc main(): void {
	fruit := ["pear", "apple", "kiwi"]
	echo map(fruit, shout)                   // ["pear!", "apple!", "kiwi!"]
	echo filter(fruit, isLong)               // ["apple"]
	echo filterMap([1, 2, 3, 4], evenHalf)   // [1, 2]
}
Ordenando
func longerFirst(a: Str, b: Str): Bool {
	return len(a) > len(b)
}

proc main(): void {
	echo sort(["pear", "Apple", "kiwi"])        // ["Apple", "kiwi", "pear"] — pelos bytes
	echo sort([true, false])                    // [false, true]
	echo sort([[2, 1], [1, 9], [1, 2]])         // [[1, 2], [1, 9], [2, 1]]
	echo sort(["fig", "banana", "kiwi"], longerFirst)

	mut ranks := [3, 1, 2]
	sort(ranks)                                 // uma instrução: ordena ranks no lugar
	echo ranks
}

Quatro funções nativas percorrem um vetor com um func, uma vez por elemento, em ordem, na thread que chamou — um proc é recusado, já que um percurso não tem onde pôr o que ele escreve:

  • map(values, transform) responde com todo elemento transformado, e mantém o tamanho do vetor. Uma transformação que não responde nada é recusada: um percurso que só age é um for each.
  • filter(values, keep) responde com os elementos para os quais keep diz true.
  • filterMap(values, transform) faz as duas coisas de uma vez: transform responde com um Result, e as cargas Ok são mantidas.
  • sort(values) responde com os elementos em ordem, e sort(values, first) na ordem que um func(a, b): Bool dá, verdadeiro quando a vem primeiro. Elementos iguais mantêm a ordem que tinham.

Sem comparador, sort usa a ordem própria dos elementos: números pelo valor, uma Str pelos bytes (então "B" vem antes de "a"), false antes de true, um átomo por onde foi mencionado primeiro, um vetor elemento por elemento, um tipo declarado campo por campo na ordem da declaração, uma união pela ordem em que as variantes foram declaradas, e os Errors de um Result antes dos Oks. Um mapa, um endereço e um valor de função não têm ordem, nem um tipo que guarde um deles, então ordená-los pede um comparador.

sort escrito como instrução, sobre um vetor mut, o ordena no lugar em vez disso.