Pular para o conteúdo

Colecoes em Clojure

Em Clojure, coleções são estruturas de dados fundamentais para armazenar e manipular conjuntos de valores. Elas seguem os princípios da imutabilidade (não podem ser modificadas diretamente) e são projetadas para uso em programação funcional. Clojure oferece várias coleções prontas, com implementações eficientes e uma interface uniforme.

  1. Listas (list ou '())
  2. Vetores (vector ou [])
  3. Conjuntos (set ou #{})
  4. Mapas (map ou {})

Essas coleções compartilham características comuns:

  • Persistência: Elas não são alteradas diretamente, mas retornam versões modificadas.
  • Interface uniforme: Podem ser usadas com funções como map, filter, reduce, etc.
  • São sequências ligadas (linked lists), imutáveis e avaliadas lazy (preguiçosamente, se necessário).
  • Usadas principalmente para representar código ou sequências lineares.

Exemplo de criação:

'(1 2 3) ; Lista literal (com apóstrofo)
(list 1 2 3) ; Usando a função list

Operações comuns:

(first '(1 2 3)) ; => 1
(rest '(1 2 3)) ; => (2 3)
(cons 0 '(1 2 3)) ; => (0 1 2 3)
  • São coleções indexadas, como arrays, mas imutáveis.
  • Mais rápidos que listas para acesso por índice.

Exemplo de criação:

[1 2 3] ; Vetor literal
(vector 1 2 3) ; Usando a função vector

Operações comuns:

(get [1 2 3] 1) ; => 2 (acesso por índice)
(conj [1 2 3] 4) ; => [1 2 3 4] (adiciona no final)
(assoc [1 2 3] 1 10) ; => [1 10 3] (modifica um índice)
  • Coleções de elementos únicos, sem ordem definida.
  • Usados para garantir que não existam duplicatas.

Exemplo de criação:

#{1 2 3} ; Literal
(set [1 2 2 3]) ; Cria um conjunto a partir de um vetor

Operações comuns:

(contains? #{1 2 3} 2) ; => true
(conj #{1 2 3} 4) ; => #{1 2 3 4}
(disj #{1 2 3} 2) ; => #{1 3}
  • Estruturas de pares chave-valor, usados para associar valores.
  • Podem ter qualquer tipo de chave e valor.

Exemplo de criação:

{:a 1 :b 2 :c 3} ; Literal
(hash-map :a 1 :b 2) ; Função hash-map

Operações comuns:

(get {:a 1 :b 2} :a) ; => 1 (acesso pelo valor da chave)
(:a {:a 1 :b 2}) ; => 1 (atalho para `get`)
(assoc {:a 1 :b 2} :c 3) ; => {:a 1 :b 2 :c 3}
(dissoc {:a 1 :b 2} :b) ; => {:a 1}
TipoUso principalVantagens
ListaSequências de dados ordenadosLazy, simples e eficiente para uso como pilha.
VetorDados indexadosAcesso rápido por índice.
ConjuntoDados únicosGarantia de unicidade.
MapaAssociação chave-valorLookup eficiente por chave.

Cenário: Suponha que você tenha uma lista de usuários e deseja processar essas informações.

(def usuarios
[{:nome "Alice" :idade 30}
{:nome "Bob" :idade 25}
{:nome "Carol" :idade 35}])
;; Filtrando usuários acima de 30 anos:
(filter #(> (:idade %) 30) usuarios)
;; => ({:nome "Carol", :idade 35})
;; Extraindo apenas os nomes:
(map :nome usuarios)
;; => ("Alice" "Bob" "Carol")
;; Criando um conjunto de idades únicas:
(set (map :idade usuarios))
;; => #{25 30 35}

Clojure oferece funções de ordem superior para manipular coleções:

  1. map: Transforma elementos.
  2. filter: Filtra elementos.
  3. reduce: Combina elementos em um único valor.
(def numeros [1 2 3 4 5])
;; Multiplica cada número por 2
(map #(* % 2) numeros)
;; => (2 4 6 8 10)
;; Filtra números ímpares
(filter odd? numeros)
;; => (1 3 5)
;; Soma todos os números
(reduce + numeros)
;; => 15