O TEMA DO FÓRUM ESTÁ EM MANUTENÇÃO. FEEDBACKS AQUI: ACESSAR

[Ruby] Hash['Aula' => 7]

Iniciado por Raizen, 02/12/2012 às 23:10

02/12/2012 às 23:10 Última edição: 16/12/2015 às 10:38 por Raizen
[box class=windowbg1]
Índice das aulas básicas
  • Aula 1 - Introdução
  • Aula 2 - Objetos
  • Aula 3 - Operações
  • Aula 4 - Condições
  • Aula 5 - Repetição
  • Aula 6 - Arrays
  • Aula 7 - Hashes
    [/box]
    [box class=windowbg1]
    Índice das aulas avançadas
  • Aula 8 - Superclasses e instâncias
    [/box]
    [box class=windowbg1]
    Índice das aulas de algoritmos
  • Aula 1 - Sort
  • Aula 2 - Busca
  • Aula 3 - Recursividade
    [/box]

    [box class=windowbg2]
    Mega Aula de Hash
    [/box]

    [box class=catbg4]
    Introdução
    [/box]

    [box class=information]  Hashes, em sua longa caminhada para ser um programador, eis de que encontra uma barreira, algo que inclusive muitos tem dificuldade, porém não é tão "do mal" assim. É uma ferramenta poderosa, sugiro que estude a aula de Arrays antes, por ter uma certa ligação com ela.

    As Hashes tem uma semelhança bem grande com as arrays, no sentido de um objeto armazenar informações de múltiplos objetos, porém uma das diferenças é de que a ordem com que os objetos são inseridos na Hash, não é uma ordem numérica e sim uma relação chave => valor.

      Explicando melhor, eu crio uma key em que poderei ter acesso ao value ligado na hash. Vou colocar na prática para ser de melhor entendimento.
    raizen = Hash['chapeu' => 'red', 'blusa' => blue']
    


       O que eu fiz acima, pode ser comparado com a seguinte imagem.


    Logo abaixo explicarei como criar Hashes de inúmeros modos, mas primeiro usarei esse como um exemplo para explicar melhor.
    Nesse caso criei uma variável raizen, e declarei ela como uma Hash, nessa Hash tem a
    key => value
    

    Eu posso acessar o value, sempre a partir da key, basicamente o seguinte.
    raizen['chapeu'], retornará o valor 'red'

       Como podem ver ele tem uma maleabilidade bem maior em criar valores para serem acessados pela variável da Hash, se comparado com as Arrays, e claro o contra-ponto é o fato de que essa maleabilidade tira vários métodos relacionados a ordem da array, que se baseiam na index da array.

    Basicamente pode procurar se aprofundar e entender melhor como é armazenado esse valor a partir daqui,
    http://en.wikipedia.org/wiki/Hash_table
    Dito isso, espero que estejam afiados, pois vamos para a parte prática :D.[/box]

    [box class=catbg4]
    Inicializando
    [/box]
    [box class=information]O jeito mais simples de declarar uma Hash é.
    variavel = Hash.new
    

    Acima será criado uma Hash vazia, ou {}, mas que o programa já identifica a variável como uma Hash.
    Você pode criar a relação key, value de 3 modos diferentes.
    variavel = Hash[key => value, key2 => value2] # O que eu acho melhor, por ser o mais didático e relacionado ao produto final
    variavel = Hash[key, value, key2, value2]
    variavel = Hash[[[key, value] , [key2, value2]]]
    


    Todos eles vão criar uma Hash com a seguinte característica
    {key => value, key2 => value2}
    


    Que claro poderia ser declarado desse modo também.
    variavel = {key => value, key2 => value2}
    

    E lembrando claro que pode pular linhas desse modo.
    variavel = {key => value, 
    key2 => value2}
    


    Também é possível criar uma hash aonde qualquer chave acionada, que não exista na Hash retorne um certo valor, por exemplo:
    variavel = Hash.new('no keys')
    

    caso eu busque uma chave inexistente ela retornará, 'no keys'.

    Vamos supor que nessa variável acima eu declare uma key.
    variavel["2"] = 'key'
    

    Ficará da seguinte maneira.

    variavel[4] == 'no keys'
    variavel["for"] == 'no keys'
    variavel["2"] == 'key'
    


    E claro além disso posso criar blocos na criação da Hash, por exemplo
    raizen = Hash.new{|raizen, key| raizen[key] = (key + 1) if key.is_a?(Integer)}
    p raizen['r'] # retorna nil
    p raizen[1] # retorna 2
    

    [/box]

    [box class=catbg4]
    Obtendo valores
    [/box]
    [box class=information]Como nas arrays, pode-se usar as hashes de maneira inteligente dentro de loops e blocos, para que ajudem a agilizar e facilitar na programação.

    Os blocos nas hashes consistem bastante na relação keys/values tendo os 3 métodos usais

    each:
    cria um bloco com ambas as keys e values
    has = {1 => 'a' , 2 => 'b'}
    has.each{|key, value| p (key + 4) ; p value}
    # produz
    # 5
    # "a"
    # 6
    # "b"
    


    each_key:
    cria um bloco com apenas as keys
    has = {1 => 'a' , 2 => 'b'}
    has.each_key{|key| p (key + key)}
    # produz
    # 2
    # 4
    


    each_value:
    cria um bloco com apenas as values
    has = {1 => 'a' , 2 => 'b'}
    has.each_value{|value| p "#{value} + 2"}
    # produz
    # "a + 2"
    # "b + 2"
    

    [/box]

    [box class=information]keys:
    retorna todas as keys(chaves) da Hash como uma array
    has = {1 => 'a' , 2 => 'b'}
    has.keys == [1, 2]
    


    values:
    retorna todas as values(valores) da Hash como uma array
    has = {1 => 'a' , 2 => 'b'}
    has.values == ["a", "b"]
    


    assoc:
    retorna a primeira associação a uma determinada key(chave), caso não exista a chave, retorna nil.
    has = {1 => 'a' , 2 => 'b'}
    has.assoc(1) == [1, "a"]
    has.assoc(5) == nil
    


    rassoc:
    mesmo que assoc, porém com os values(valores)
    has = {1 => 'a' , 2 => 'b'}
    has.rassoc('a') == [1, "a"]
    has.rassoc(5) == nil
    


    has_key?:
    alias como include?, key?, member?
    retorna true ou false se tem ou não determinada key.
    has = {:let => 'c' , :not => 't'}
    has.has_key?('c') == false # é considerado apenas as keys(chaves)
    has.include?(:let) == true
    


    has_value?:
    alias como value?
    retorna true ou false se tem ou não determinado value.
    has = {:let => 'c' , :not => 't'}
    p has.has_value?(:let) == false # é considerado apenas os values(valores)
    p has.value?('t') == true
    


    size:
    alias como length
    retorna a quantidade de pars key => value na Hash
    has = {:let => 'c' , :not => 't'}
    p has.size == 2
    


    fetch:
    retorna o value de determinada key
    has = {:let => 'c' , :not => 't'}
    has.fetch(:let) == 'c'
    

    Com exceções
    has = {:let => 'c' , :not => 't'}
    has.fetch(:leeet, "no key") == "no key"
    

    Pode ser usado blocos nas exceções
    has = {:let => 'c' , :not => 't'}
    has.fetch('not'){|val| "#{val} key"} == "not key"
    


    empty:
    retorna se a array está vazia
    has = {:let => 'c' , :not => 't'}
    has.empty == false
    

    [/box]

    [box class=catbg4]
    Manipulando as Hashes
    [/box]
    [box class=information]delete:
    deleta uma key(chave) e seu par value(valor)
    has = {:let => 'c' , :not => 't'}
    has.delete(:let) # retorna 'c'
    has == {:not => 't'}
    


    delete_if:
    deleta uma key(chave) e seu par value(valor) se atingir a condição do bloco
    has = {1 => 'c' , 2 => 't'}
    has.delete_if{|key| key <= 1 }
    has == {2 => 't'}
    


    flatten
    retorna a Hash em uma array retirando os pares dela, pode ser usado com um argumento de level, para continuar a processo após ele ser considerado uma array.
    has = {1 => 'c' , 2 => 't'}
    has.flatten == [1, 'c', 2, 't']
    


    replace
    muda a hash em uma nova hash dentro do argumento do replace.
    has = {1 => 'c' , 2 => 't'}
    has.replace({'a' => 'c', 'b' => 32})
    has == {'a' => 'c', 'b' => 32}
    


    invert
    inverte os pares, keys viram values e vice-versa, porém o valor da hash antiga se mantém intacta, apenas retorna com os valores invertidos
    has = {1 => 'c' , 2 => 't'}
    has.invert == {'c' => 1 , 't' => 2}
    


    shift
    retira o primeiro par da hash
    has = {1 => 'c' , 2 => 't'}
    has.shift # retorna [1, 'c']
    has == {2 => 't'}
    

    [/box]

    [box class=catbg4]
    Conclusão e Tarefa
    [/box]
    Novamente eu não colocarei todos os métodos por serem muitos, tentei colocar os principais, podem verificar mais aqui, e de onde me baseei em alguns que estão no tópico.
    http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-has_key-3F

    A seguinte tarefa, Eu pretendo usar o Color.new para indicar as cores, mas ficar chamando toda hora eles com o sistema RGB é muito trabalhoso, quero que façam uma Hash que ou :symbol ou "String", eu possa colocar por exemplo has['red'] e sair a cor vermelha para o Color.new
    Lembrando que o Color precisa de 4 parâmetros(R, G, B, T) R = red, G = green, B = blue, T = transparência

    Lembrando que pode colocar classes dentro das Hashes,
    queria para as cores primarias e secundarias.
    Se precisarem da tabela de cores :D

    http://shibolete.tripod.com/RGB.html

Essa tarefa me confundiu muito, só consegui fazer a Hash e acho que muito mal feita...
Queria saber como provar isso...
color_hash = {'red' => Color.new(255,0,0,0), 'green' => Color.new(0,255,0,0),
'blue' => Color.new(0,0,255,0)}

Dá-me umas dicas raizen o/
"Pode-se enganar a todos por algum tempo; pode-se enganar alguns por todo o tempo; mas não se pode enganar a todos todo o tempo."

Ei, você, você mesmo! Tá afim de ver um projeto legal? Clica embaixo!


10/08/2013 às 19:07 #2 Última edição: 10/08/2013 às 19:51 por Ryugo
 :*-*: Consegui  :*-*:

Acho que fiz exatamente como o esperado,se não,como era pra fazer?

Aqui:
# Cria um sprite para armazenar o bitmap
sprite = Sprite.new

# Então cria o bitmap e o anexamos ao sprite
sprite.bitmap = Bitmap.new(544, 416) #Retangulo do tamanho do tela

# Cria as cores
color = {:red => Color.new(255,0,0), :green => Color.new(0,255,0), :blue => Color.new(0,0,255),
:yellow => Color.new(255,255,0),:orange => Color.new(255,165,0),:pink => Color.new(255,192,203)}

# Pintamos o bitmap
sprite.bitmap.fill_rect(sprite.bitmap.rect, color[:orange]) # << Altere aqui a cor
msgbox 'Uhuu,funcionou ^^'

# Atualizamos a tela para exibir o bitmap
loop { 
  Graphics.update
  Input.update
  break if Input.trigger?(:C) #Aperte Enter
}

#Agradecimento a Kyo Panda(Arthur) e Gab! por ajudarem


Agradeço ao Kyo e ao Gab! pela ajuda nesse script.E agradeço de mais a você Raizen pelas suas aulas  :ok:

Ah,e se der olha lá meu post na aula 5 tbm :ded:


Té  :wow:

Fiz =), mas só as três cores :ok:?
def teste
   has = Hash.new
   has["Blue"] = Color.new(0, 0, 255, 0)
   has["Red"] = Color.new(255, 0, 0, 0)
   has["Yellow"] = Color.new(255, 255, 0, 0)

p has["Blue"]
p has["Red"]
p has["Yellow"]
end
teste


Correto? PS: Fiz desde método pois achei o outro mais complicado x)
Espaço RPG Maker
  (clique na imagem abaixo)

Basicamente isso ae manolo  :ok:

Agora acho que está na hora de novos scripts seu heim  :malvado:

Para colocar tudo na prática

Kkk acho que vai demorar de eu criar outro, só estou cuidando daquele lá da MRM e estudando, pois um sábio me disse que: Eu não posso querer aprender algo que demora anos em uma semana, é a mesma coisa de eu tentar completar uma faculdade em um dia, ou seja, posso até conseguir fazer algo, mas o resultado será apenas dor de cabeça x)
Espaço RPG Maker
  (clique na imagem abaixo)

Eu não entendi muito bem o que você queria, por isso acho que fiz muito parecido ou até uma cópia com o do Ryugo.

#-------------------------------------------------------------------------------
#                           Dever de Hashes
#-------------------------------------------------------------------------------

sprite = Sprite.new
sprite.bitmap = Bitmap.new(544,416)
color = {:red => Color.new(255,0,0,), :blue => Color.new(0,0,255,), :green => Color.new(0,255,0,),
:yellow => Color.new(255,255,0,), :cyan => Color.new(0,255,255,), :pink => Color.new(255,0,255,),
:white => Color.new(255,255,255,), :black => Color.new(0,0,0,)}
sprite.bitmap.fill_rect(sprite.bitmap.rect, color[:cyan])
loop { 
  Graphics.update
  Input.update
  break if Input.trigger?(:C)
}


Se não for isso me explique como é.