segunda-feira, 23 de abril de 2012

2 - Listas em AutoLisp (list) - PARTE 1 - Funções: list, car, cdr e nth

Olá Pessoal, neste post eu irei falar sobre a manipulação de listas no AutoLisp, que pode-se dizer que é a estrutura mais importante que existe em lisp, isto fica mais evidente com o fato de LISP significar LISt Processing (processamento de listas).

Neste post, eu irei focar na manipulação de listas através dos comandos básicos presentes na linguagem. Num post futuro, irei falar dos comandos para manipulação de listas, utilizando o ActiveX, que é uma expansão do Visual Lisp, que amplia em muito o AutoLisp.



CRIANDO LISTAS


Para criar uma lista, usamos a palavra chave list, seguido dos itens no qual se deseja adicionar a lista. Estes itens podem ser de qualquer tipo, números, strings, outras listas (sub listas), ou uma mistura de várias coisas.
Exemplos:
- criando uma lista com os números 1, 2 e 3: (list 1 2 3) 
   retorna: (1 2 3)
- criando uma lista com as strings "Autolisp" e "Brasil": (list "Autolisp" "Brasil")
   retorna: ("Autolisp" "Brasil")
- criando uma lista que contém as duas listas dos exemplos anteriores: (list (list 1 2 3) (list "Autolisp" "Brasil"))
  retorna: ((1 2 3) ("Autolisp" "Brasil"))

O caractere ' nos permite substituir a palavra chave list em alguns casos, na verdade este caractere é equivalente ao comando quota do AutoLisp, que não entrarei em detalhes.
Exemplo do uso do caractere ' , onde queremos criar uma lista com os seguintes itens: o número 1, uma sub lista com os números 2 e 3, e o número 4:
(list 1 '(2 3) 4)
retorna: (1 (2 3) 4)

Exemplo que não funciona com o caractere ' :
('( 1 2 3)) (NÃO FUNCIONA)

Para fazer o exemplo anterior funcionar, podemos associar a lista em uma variável qualquer, assim podemos utilizar do caractere ' , como mostrado no exemplo abaixo:
(setq variavel '( 1 2 3))
que retorna a lista: (1 2 3)



RECUPERANDO ELEMENTOS DA LISTA

1 - FUNÇÕES CAR E CDR
Uma maneira de recuperar os elementos de uma lista, é utilizando as funções car e cdr. A função car, recupera sempre o primeiro elemento de uma lista, que pode ser um átomo ou uma sub lista, ou seja, qualquer coisa que esteja como primeiro item da lista.
Exemplos, utilizando a função car:
- Exemplo 1: Temos a seguinte lista: (10 20 30 40)
                      Utilizando da função car: (car (list 10 20 30 40))
                      Obtemos o átomo: 10
- Exemplo 2: Temos a váriavel listaObjetos com os itens "autolisp", 30, 3.14
                      Criando a lista: (setq listaObjetos (list "autolisp" 30 3.14))
                      Lista gerada: ("autolisp" 30 3.14)
                      Utilizando da função car: (car listaObjetos)
                      Obtemos o átomo: "autolisp"
- Exemplo 3: Temos uma lista com uma sub lista contendo os números 1, 2 e 3, e uma outra sub lista contendo os números 4, 5 e 6.
                       Utilizando da função car: (car (list (list 1 2 3) (list 4 5 6)))
                       Obtemos a lista: (1 2 3)


A função cdr, recupera todos os itens da lista, exceto o primeiro. Utilizando os mesmo exemplos anteriores, temos:

Exemplos, utilizando a função cdr:
- Exemplo 1: Temos a seguinte lista: (10 20 30 40)
                      Utilizando da função cdr: (cdr (list 10 20 30 40))
                      Obtemos a lista: (20 30 40)
- Exemplo 2: Temos a váriavel listaObjetos com os itens "autolisp", 30, 3.14
                      Criando a lista: (setq listaObjetos (list "autolisp" 30 3.14))
                      Lista gerada: ("autolisp" 30 3.14)
                      Utilizando da função cdr: (cdr listaObjetos)
                      Obtemos a lista: (30 3.14)
- Exemplo 3: Temos uma lista com uma sub lista contendo os números 1, 2 e 3, e uma outra sub lista contendo os números 4, 5 e 6.
                       Utilizando da função cdr: (cdr (list (list 1 2 3) (list 4 5 6)))
                       Obtemos uma lista com um único item, que é uma sub lista: ((4 5 6))


Para obtermos por exemplo o segundo item da lista, precisamos utilizarmos a função cdr, que retorna a lista sem o primeiro item seguido da função car, como mostrado abaixo para a seguinte lista (10 20 30 40 50):
(setq lista (list 10 20 30 40 50))
(setq novaLista (cdr lista))
(setq novaNovaLista (car novaLista))

Recuperar os itens desta forma é bem ineficiente, pois se tivermos que recuperar o quarto item, temos que invocar três vezes a função cdr e por fim a função car. Felizmente, lisp permite concatenar as funções cdr e car, assim para o caso anterior, podemos usar a função cadddr, que pode ser lida de trás para frente, onde cada "d" significa uma execução da função cdr, e cada "a" significa a execução da função car.

Abaixo temos uma listagem de funções permitidas com a junção das funções car com cdr, lembrando que a chamada das funções car e cdr é feita de trás para frente nestas funções:

caar cadr cdar cddr caaar caadr cadar caddr cdaar cdadr cddar cdddr caaaar caaadr caadar caaddr cadaar cadadr caddar cadddr cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr


Infelizmente, nem sempre temos uma função que desejamos, quando vamos obter um item, por exemplo para pegar o quinto item da lista (10 20 30 40 50), temos que executar quatro vezes a função cdr, seguido de uma execução da função car. Não existe a função caddddr em lisp, então temos que mesclar as funções disponíveis para se conseguir o efeito desejado.


2 - FUNÇÃO NTH

Através da função nth, podemos acessar de forma mais direta elementos da lista. Sabendo-se qual a posição do elemento na lista, a função nth é usada da seguinte forma: (nth x listaA) , onde x é a posição do elemento na lista e listaA é a lista no qual está efetuando a operação. OBS: a primeira posição da lista é sempre 0, e a última posição da lista é o número de elementos menos um.

Exemplos, utilizando a função nth:
- Exemplo 1: Temos a seguinte lista: (10 20 30 40)
                     Utilizando da função nth, queremos obter o terceiro elemento da lista: (nth 2 (list 10 20 30 40))
                     Obtemos o átomo: 30
- Exemplo 2: Temos a váriavel listaObjetos com os itens "autolisp", 30, 3.14
                      Criando a lista: (setq listaObjetos (list "autolisp" 30 3.14))
                      Lista gerada: ("autolisp" 30 3.14)
                    Utilizando da função nth, queremos obter o primeiro elemento da lista: (nth 0 listaObjetos)
                      Obtemos o átomo: "autolisp"
- Exemplo 3: Temos uma lista com uma sub lista contendo os números 1, 2 e 3, e uma outra sub lista contendo os números 4, 5 e 6.
                    Utilizando da função nth, queremos obter o segundo elemento da lista: (nth 1 (list (list 1 2 3) (list 4 5 6)))
                    Obtemos a sub lista: (4 5 6)




OBSERVAÇÕES:

- Quando tenta-se obter um elemento inexistente de uma lista, como por exemplo uma lista com 3 elementos, tenta-se acessar o quinto elemento, é obtido o valor nil;
- Um erro é obtido em situações no qual é aplicados as funções car, cdr ou nth, em elementos que não são listas;



No próximo post, irei continuar falando de outras funções que manipulam listas.

Nenhum comentário:

Postar um comentário