Comparação de linguagens de programação (matriz associativa) - Comparison of programming languages (associative array)

Esta comparação de linguagens de programação (matrizes associativas) compara os recursos de estruturas de dados de matriz associativa ou processamento de pesquisa de matriz para mais de 40 linguagens de programação de computador .

Suporte de linguas

A seguir está uma comparação de matrizes associativas (também "mapeamento", "hash" e "dicionário") em várias linguagens de programação.

Awk

Awk tem suporte embutido em nível de linguagem para matrizes associativas.

Por exemplo:

phonebook["Sally Smart"] = "555-9999"
phonebook["John Doe"] = "555-1212"
phonebook["J. Random Hacker"] = "555-1337"

O código a seguir percorre uma matriz associada e imprime seu conteúdo:

for (name in phonebook) {
	print name, " ", phonebook[name]
}

O usuário pode pesquisar elementos em uma matriz associativa e excluir elementos da matriz.

O seguinte mostra como matrizes associativas multidimensionais podem ser simuladas no Awk padrão usando concatenação e a variável separadora de string integrada SUBSEP:

{ # for every input line
	multi[$1 SUBSEP $2]++;
}
#
END {
	for (x in multi) {
		split(x, arr, SUBSEP);
		print arr[1], arr[2], multi[x];
	}
}

C

Não há implementação padrão de matrizes associativas em C , mas uma biblioteca de terceiros, C Hash Table, com licença BSD, está disponível.

Outra biblioteca de terceiros, uthash, também cria matrizes associativas a partir de estruturas C. Uma estrutura representa um valor e um dos campos da estrutura serve como a chave.

Finalmente, a biblioteca GLib também suporta matrizes associativas, junto com muitos outros tipos de dados avançados e é a implementação recomendada do Projeto GNU.

Semelhante ao GLib , o framework Core Foundation multiplataforma da Apple fornece vários tipos básicos de dados. Em particular, existem CFDictionary e CFMutableDictionary contados por referência.

C #

C # usa as classes de coleção fornecidas pelo .NET Framework . O tipo de array associativo mais comumente usado é System.Collections.Generic.Dictionary<TKey, TValue>, que é implementado como uma tabela hash mutável. O System.Collections.Immutablepacote relativamente novo , disponível nas versões 4.5 e superiores do .NET Framework, e em todas as versões do .NET Core , também inclui o System.Collections.Immutable.Dictionary<TKey, TValue>tipo, que é implementado usando uma árvore AVL . Os métodos que normalmente alterariam o objeto no local, em vez disso, retornam um novo objeto que representa o estado do objeto original após a mutação.

Criação

O seguinte demonstra três meios de preencher um dicionário mutável:

  • o Addmétodo, que adiciona uma chave e um valor e lança uma exceção se a chave já existir no dicionário;
  • atribuir ao indexador, que sobrescreve qualquer valor existente, se houver; e
  • atribuição à propriedade de apoio do indexador, para a qual o indexador é um açúcar sintático (não aplicável a C #, consulte os exemplos de F # ou VB.NET ).
Dictionary<string, string> dic = new Dictionary<string, string>();
dic.Add("Sally Smart", "555-9999");
dic["John Doe"] = "555-1212";
// Not allowed in C#.
// dic.Item("J. Random Hacker") = "553-1337";
dic["J. Random Hacker"] = "553-1337";

O dicionário também pode ser inicializado durante a construção usando um "inicializador de coleção", que compila para chamadas repetidas para Add.

var dic = new Dictionary<string, string> {
    { "Sally Smart", "555-9999" },
    { "John Doe", "555-1212" },
    { "J. Random Hacker", "553-1337" }
};

Acesso por chave

Os valores são recuperados principalmente usando o indexador (que lança uma exceção se a chave não existir) e o TryGetValuemétodo, que tem um parâmetro de saída para o valor procurado e um valor de retorno booleano indicando se a chave foi encontrada.

var sallyNumber = dic["Sally Smart"];
var sallyNumber = (dic.TryGetValue("Sally Smart", out var result) ? result : "n/a";

Neste exemplo, o sallyNumbervalor agora conterá a string "555-9999".

Enumeração

Um dicionário pode ser visto como uma sequência de chaves, sequência de valores ou sequência de pares de chaves e valores representados por instâncias do KeyValuePair<TKey, TValue>tipo, embora não haja garantia de ordem. Para um dicionário classificado, o programador pode escolher usar um SortedDictionary<TKey, TValue>ou usar o método de extensão .Sort LINQ ao enumerar.

O seguinte demonstra a enumeração usando um loop foreach :

// loop through the collection and display each entry.
foreach(KeyValuePair<string,string> kvp in dic)
{
    Console.WriteLine("Phone number for {0} is {1}", kvp.Key, kvp.Value);
}

C ++

C ++ tem uma forma de array associativo chamado std::map(consulte Biblioteca de modelos padrão # Containers ). Pode-se criar um mapa de catálogo telefônico com o seguinte código em C ++:

#include <map>
#include <string>
#include <utility>
 
int main() {
	std::map<std::string, std::string> phone_book;
	phone_book.insert(std::make_pair("Sally Smart", "555-9999"));
	phone_book.insert(std::make_pair("John Doe", "555-1212"));
	phone_book.insert(std::make_pair("J. Random Hacker", "553-1337"));
}

Ou com menos eficiência, pois isso cria std::stringvalores temporários :

#include <map>
#include <string>
 
int main() {
	std::map<std::string, std::string> phone_book;
	phone_book["Sally Smart"] = "555-9999";
	phone_book["John Doe"] = "555-1212";
	phone_book["J. Random Hacker"] = "553-1337";
}

Com a extensão das listas de inicialização em C ++ 11, as entradas podem ser adicionadas durante a construção de um mapa, conforme mostrado abaixo:

#include <map>
#include <string>

int main() {
	std::map<std::string, std::string> phone_book {
		{"Sally Smart", "555-9999"},
		{"John Doe", "555-1212"},
		{"J. Random Hacker", "553-1337"}
	};
}

Você pode iterar pela lista com o seguinte código (C ++ 03):

std::map<std::string, std::string>::iterator curr, end;
for(curr = phone_book.begin(), end = phone_book.end();  curr != end;  ++curr)
	std::cout <<  curr->first << " = " << curr->second << std::endl;

A mesma tarefa em C ++ 11:

for(const auto& curr : phone_book)
        std::cout <<  curr.first << " = " << curr.second << std::endl;

Usando a ligação estruturada disponível em C ++ 17 :

for (const auto& [name, number] : phone_book) {
    std::cout << name << " = " << number << std::endl;
}

Em C ++, a std::mapclasse é modelada, o que permite que os tipos de dados de chaves e valores sejam diferentes para diferentes mapinstâncias. Para uma determinada instância da mapclasse, as chaves devem ser do mesmo tipo base. O mesmo deve ser verdadeiro para todos os valores. Embora std::mapseja tipicamente implementado usando uma árvore de pesquisa binária de autobalanceamento , C ++ 11 define um segundo mapa chamado std::unordered_map, que tem as características algorítmicas de uma tabela hash. Esta também é uma extensão de fornecedor comum para a Biblioteca de Modelos Padrão (STL), normalmente chamada hash_map, disponível em implementações como SGI e STLPort.

CFML

Uma estrutura em CFML é equivalente a uma matriz associativa:

dynamicKeyName = "John Doe";
phoneBook = {
	"Sally Smart" = "555-9999",
	"#dynamicKeyName#" = "555-4321",
	"J. Random Hacker" = "555-1337",	
	UnknownComic = "???"
};
writeOutput(phoneBook.UnknownComic); // ???
writeDump(phoneBook); // entire struct

Cobra

Inicializando um dicionário vazio e adicionando itens no Cobra :

 dic as Dictionary<of String, String> = Dictionary<of String, String>()
 dic.add('Sally Smart', '555-9999')
 dic.add('John Doe', '555-1212')
 dic.add('J. Random Hacker', '553-1337')
 
 assert dic['Sally Smart'] == '555-9999'

Alternativamente, um dicionário pode ser inicializado com todos os itens durante a construção:

 dic = {
           'Sally Smart':'555-9999',
           'John Doe':'555-1212',
           'J. Random Hacker':'553-1337'
       }

O dicionário pode ser enumerado por um loop for, mas não há uma ordem garantida:

 for key, val in dic
     print "[key]'s phone number is [val]"

D

D oferece suporte direto para matrizes associativas na linguagem central; tais arrays são implementados como uma tabela hash encadeada com árvores binárias. O exemplo equivalente seria:

int main() {
	string[ string ] phone_book;
	phone_book["Sally Smart"] = "555-9999";
	phone_book["John Doe"] = "555-1212";
	phone_book["J. Random Hacker"] = "553-1337";
	return 0;
}

Chaves e valores podem ser de qualquer tipo, mas todas as chaves em uma matriz associativa devem ser do mesmo tipo, e o mesmo vale para valores dependentes.

O loop por todas as propriedades e valores associados, e imprimi-los, pode ser codificado da seguinte forma:

foreach (key, value; phone_book) {
        writeln("Number for " ~ key ~ ": " ~ value );
}

Uma propriedade pode ser removida da seguinte forma:

phone_book.remove("Sally Smart");

Delphi

Delphi suporta vários contêineres padrão, incluindo TDictionary <T>:

uses
  SysUtils,
  Generics.Collections;

var
  PhoneBook: TDictionary<string, string>;
  Entry: TPair<string, string>;

begin
  PhoneBook := TDictionary<string, string>.Create;
  PhoneBook.Add('Sally Smart', '555-9999');
  PhoneBook.Add('John Doe', '555-1212');
  PhoneBook.Add('J. Random Hacker', '553-1337');

  for Entry in PhoneBook do
    Writeln(Format('Number for %s: %s',[Entry.Key, Entry.Value]));
end.

As versões do Delphi anteriores a 2009 não oferecem suporte direto para matrizes associativas. No entanto, matrizes associativas podem ser simuladas usando a classe TStrings:

procedure TForm1.Button1Click(Sender: TObject);
var
  DataField: TStrings;
  i: Integer;
begin
  DataField := TStringList.Create;

  DataField.Values['Sally Smart'] := '555-9999';
  DataField.Values['John Doe'] := '555-1212';
  DataField.Values['J. Random Hacker'] := '553-1337';

  // access an entry and display it in a message box
  ShowMessage(DataField.Values['Sally Smart']);

  // loop through the associative array 
  for i := 0 to DataField.Count - 1 do
  begin
    ShowMessage('Number for ' + DataField.Names[i] + ': ' + DataField.ValueFromIndex[i]);
  end;

  DataField.Free;
end;

Erlang

Erlang oferece muitas maneiras de representar mapeamentos; três dos mais comuns na biblioteca padrão são listas de chaves, dicionários e mapas.

Keylists

As listas de chaves são listas de tuplas , em que o primeiro elemento de cada tupla é uma chave e o segundo é um valor. Funções para operar em listas de teclas são fornecidas no listsmódulo.

PhoneBook = [{"Sally Smith", "555-9999"},
             {"John Doe", "555-1212"},
             {"J. Random Hacker", "553-1337"}].

O acesso a um elemento da lista de teclas pode ser feito com a lists:keyfind/3função:

{_, Phone} = lists:keyfind("Sally Smith", 1, PhoneBook),
io:format("Phone number: ~s~n", [Phone]).

Dicionários

Os dicionários são implementados no dictmódulo da biblioteca padrão. Um novo dicionário é criado usando a dict:new/0função e novos pares de chave / valor são armazenados usando a dict:store/3função:

PhoneBook1 = dict:new(),
PhoneBook2 = dict:store("Sally Smith", "555-9999", Dict1),
PhoneBook3 = dict:store("John Doe", "555-1212", Dict2),
PhoneBook = dict:store("J. Random Hacker", "553-1337", Dict3).

Essa inicialização serial seria representada de forma mais linguística em Erlang com a função apropriada:

PhoneBook = dict:from_list([{"Sally Smith", "555-9999"},
                            {"John Doe", "555-1212"},
                            {"J. Random Hacker", "553-1337"}]).

O dicionário pode ser acessado usando a dict:find/2função:

{ok, Phone} = dict:find("Sally Smith", PhoneBook),
io:format("Phone: ~s~n", [Phone]).

Em ambos os casos, qualquer termo Erlang pode ser usado como chave. As variações incluem o orddictmódulo, implementação de dicionários ordenados e gb_treesimplementação de árvores balanceadas gerais.

Mapas

Os mapas foram introduzidos no OTP 17.0 e combinam os pontos fortes de listas e dicionários. Um mapa é definido usando a sintaxe #{ K1 => V1, ... Kn => Vn }:

PhoneBook = #{"Sally Smith" => "555-9999",
              "John Doe" => "555-1212",
              "J. Random Hacker" => "553-1337"}.

Funções básicas para interagir com mapas estão disponíveis no mapsmódulo. Por exemplo, a maps:find/2função retorna o valor associado a uma chave:

{ok, Phone} = maps:find("Sally Smith", PhoneBook),
io:format("Phone: ~s~n", [Phone]).

Ao contrário dos dicionários, os mapas podem ser padronizados em:

#{"Sally Smith", Phone} = PhoneBook,
io:format("Phone: ~s~n", [Phone]).

Erlang também fornece sintaxe de açúcar para atualizações funcionais - criando um novo mapa baseado em um existente, mas com valores modificados ou chaves adicionais:

PhoneBook2 = PhoneBook#{
    % the `:=` operator updates the value associated with an existing key
    "J. Random Hacker" := "355-7331",

    % the `=>` operator adds a new key-value pair, potentially replacing an existing one
    "Alice Wonderland" => "555-1865"
}

F #

Mapa <'Chave,' Valor>

Em tempo de execução, F # fornece o Collections.Map<'Key,'Value>tipo, que é uma árvore AVL imutável .

Criação

O exemplo a seguir chama o Mapconstrutor, que opera em uma lista (uma sequência de elementos delimitada por ponto e vírgula entre colchetes) de tuplas (que em F # são sequências de elementos delimitadas por vírgulas).

let numbers =
    [
        "Sally Smart", "555-9999"; 
        "John Doe", "555-1212";
        "J. Random Hacker", "555-1337"
    ] |> Map
Acesso por chave

Os valores podem ser pesquisados ​​por meio de um dos Mapmembros, como seu indexador ou Itempropriedade (que lança uma exceção se a chave não existir) ou a TryFindfunção, que retorna um tipo de opção com um valor de Some <result>, para uma pesquisa bem-sucedida ou None, para um malsucedido. A correspondência de padrões pode então ser usada para extrair o valor bruto do resultado ou um valor padrão pode ser definido.

let sallyNumber = numbers.["Sally Smart"]
// or
let sallyNumber = numbers.Item("Sally Smart")
let sallyNumber =
    match numbers.TryFind("Sally Smart") with
    | Some(number) -> number
    | None         -> "n/a"

Em ambos os exemplos acima, o sallyNumbervalor conteria a string "555-9999".

Dicionário <'TKey,' TValue>

Como o F # é uma linguagem .NET, ele também tem acesso aos recursos do .NET Framework , incluindo o System.Collections.Generic.Dictionary<'TKey,'TValue>tipo (que é implementado como uma tabela hash ), que é o tipo de matriz associativa principal usado em C # e Visual Basic. Este tipo pode ser preferido ao escrever código que se destina a operar com outras linguagens no .NET Framework, ou quando as características de desempenho de uma tabela hash são preferidas às de uma árvore AVL.

Criação

A dictfunção fornece um meio de criar convenientemente um dicionário .NET que não deve sofrer mutação; ele aceita uma sequência de tuplas e retorna um objeto imutável que o implementa IDictionary<'TKey,'TValue>.

let numbers =
    [
        "Sally Smart", "555-9999"; 
        "John Doe", "555-1212";
        "J. Random Hacker", "555-1337"
    ] |> dict

Quando um dicionário mutável é necessário, o construtor de System.Collections.Generic.Dictionary<'TKey,'TValue>pode ser chamado diretamente. Consulte o exemplo C # nesta página para obter informações adicionais.

let numbers = System.Collections.Generic.Dictionary<string, string>()
numbers.Add("Sally Smart", "555-9999")
numbers.["John Doe"] <- "555-1212"
numbers.Item("J. Random Hacker") <-  "555-1337"
Acesso por chave

IDictionaryas instâncias têm um indexador que é usado da mesma maneira que Map, embora o equivalente a TryFindseja TryGetValue, que tem um parâmetro de saída para o valor procurado e um valor de retorno booleano indicando se a chave foi encontrada.

let sallyNumber =
    let mutable result = ""
    if numbers.TryGetValue("Sally Smart", &result) then result else "n/a"

F # também permite que a função seja chamada como se não tivesse nenhum parâmetro de saída e, em vez disso, retorne uma tupla contendo seu valor de retorno regular e o valor atribuído ao parâmetro de saída:

let sallyNumber =
    match numbers.TryGetValue("Sally Smart") with
    | true, number -> number
    | _     -> "n/a"

Enumeração

Um dicionário ou mapa pode ser enumerado usando Seq.map.

// loop through the collection and display each entry.
numbers |> Seq.map (fun kvp -> printfn "Phone number for %O is %O" kvp.Key kvp.Value)

FoxPro

O Visual FoxPro implementa o mapeamento com a classe Collection.

mapping = NEWOBJECT("Collection")
mapping.Add("Daffodils", "flower2") && Add(object, key) – key must be character
index   = mapping.GetKey("flower2") && returns the index value 1
object  = mapping("flower2")        && returns "Daffodils" (retrieve by key)
object  = mapping(1)                && returns "Daffodils" (retrieve by index)

GetKey retorna 0 se a chave não for encontrada.

Ir

Go tem suporte integrado em nível de linguagem para matrizes associativas, chamadas de "mapas". O tipo de chave de um mapa pode ser apenas booleano, numérico, string, array, estrutura, ponteiro, interface ou tipo de canal.

Um tipo de mapa é escrito: map[keytype]valuetype

Adicionando elementos um de cada vez:

phone_book := make(map[string] string) // make an empty map
phone_book["Sally Smart"] = "555-9999"
phone_book["John Doe"] = "555-1212"
phone_book["J. Random Hacker"] = "553-1337"

Um literal de mapa:

phone_book := map[string] string {
	"Sally Smart": "555-9999",
	"John Doe": "555-1212",
	"J. Random Hacker": "553-1337",
}

Iterando em um mapa:

// over both keys and values
for key, value := range phone_book {
	fmt.Printf("Number for %s: %s\n", key, value)
}

// over just keys
for key := range phone_book {
	fmt.Printf("Name: %s\n", key)
}

Haskell

A linguagem de programação Haskell fornece apenas um tipo de contêiner associativo - uma lista de pares:

m = [("Sally Smart", "555-9999"), ("John Doe", "555-1212"), ("J. Random Hacker", "553-1337")]

main = print (lookup "John Doe" m)

saída:

Just "555-1212"

Observe que a função de pesquisa retorna um valor "Maybe", que é "Nothing" se não for encontrado, ou "Apenas 'resultado ' " quando encontrado.

GHC , a implementação mais comumente usada de Haskell, fornece mais dois tipos de contêineres associativos. Outras implementações também podem fornecer isso.

Um são os mapas funcionais polimórficos (representados como árvores binárias balanceadas imutáveis):

import qualified Data.Map as M

m = M.insert "Sally Smart" "555-9999" M.empty
m' = M.insert "John Doe" "555-1212" m
m'' = M.insert "J. Random Hacker" "553-1337" m'

main = print (M.lookup "John Doe" m'' :: Maybe String)

saída:

Just "555-1212"

Uma versão especializada para chaves inteiras também existe como Data.IntMap.

Finalmente, uma tabela hash polimórfica:

import qualified Data.HashTable as H

main = do m <- H.new (==) H.hashString
          H.insert m "Sally Smart" "555-9999"
          H.insert m "John Doe" "555-1212"
          H.insert m "J. Random Hacker" "553-1337"
          foo <- H.lookup m "John Doe"
          print foo

saída:

Just "555-1212"

Listas de pares e mapas funcionais fornecem uma interface puramente funcional, que é mais idiomática em Haskell. Em contraste, as tabelas de hash fornecem uma interface imperativa na mônada de IO .

Java

Em Java, os arrays associativos são implementados como "mapas", que fazem parte da estrutura de coleções Java . Desde J2SE 5.0 e a introdução de genéricos em Java, as coleções podem ter um tipo especificado; por exemplo, uma matriz associativa que mapeia strings para strings pode ser especificada da seguinte maneira:

Map<String, String> phoneBook = new HashMap<String, String>();
phoneBook.put("Sally Smart", "555-9999");
phoneBook.put("John Doe", "555-1212");
phoneBook.put("J. Random Hacker", "555-1337");

O getmétodo é usado para acessar uma chave; por exemplo, o valor da expressão phoneBook.get("Sally Smart")é "555-9999". Este código usa um mapa hash para armazenar a matriz associativa, chamando o construtor da HashMapclasse. No entanto, como o código usa apenas métodos comuns à interface Map, uma árvore binária de autobalanceamento pode ser usada chamando o construtor da TreeMapclasse (que implementa a subinterface SortedMap), sem alterar a definição da phoneBookvariável ou o resto do código ou usando outras estruturas de dados subjacentes que implementam a Mapinterface.

A função hash em Java, usada por HashMap e HashSet, é fornecida pelo Object.hashCode()método. Como toda classe em Java herda de Object, todo objeto tem uma função hash. Uma classe pode substituir a implementação padrão de hashCode()para fornecer uma função hash personalizada mais de acordo com as propriedades do objeto.

A Objectclasse também contém o equals(Object)método, que testa a igualdade de um objeto com outro objeto. Estruturas de dados hash em Java dependem de objetos que mantêm o seguinte contrato entre seus métodos hashCode()e equals():

Para dois objetos a e b ,

a.equals(b) == b.equals(a)
if a.equals(b), then a.hashCode() == b.hashCode()

Para manter este contrato, uma classe que substitui equals()também deve substituir hashCode(), e vice-versa, de forma que hashCode()seja baseada nas mesmas propriedades (ou um subconjunto das propriedades) que equals().

Um outro contrato que uma estrutura de dados em hash tem com o objeto é que os resultados dos métodos hashCode()e equals()não serão alterados depois que o objeto for inserido no mapa. Por esse motivo, geralmente é uma boa prática basear a função hash nas propriedades imutáveis do objeto.

Analogamente, TreeMap e outras estruturas de dados classificados requerem que uma ordem seja definida no tipo de dados. Ou o tipo de dado já deve ter definido seu próprio ordenamento, implementando a Comparableinterface; ou um personalizado Comparatordeve ser fornecido no momento em que o mapa é construído. Como no HashMap acima, a ordem relativa das chaves em um TreeMap não deve mudar depois de inseridas no mapa.

JavaScript

JavaScript (e sua versão padronizada, ECMAScript ) é uma linguagem orientada a objetos baseada em protótipo .

Mapa e WeakMap

O JavaScript moderno lida com matrizes associativas, usando as classes Mape WeakMap. Um mapa não contém nenhuma chave por padrão; ele contém apenas o que é explicitamente colocado nele. As chaves e valores podem ser de qualquer tipo (incluindo funções, objetos ou qualquer primitivo).

Criação

Um mapa pode ser inicializado com todos os itens durante a construção:

const phoneBook = new Map([
    ["Sally Smart", "555-9999"],
    ["John Doe", "555-1212"],
    ["J. Random Hacker", "553-1337"],
]);

Como alternativa, você pode inicializar um mapa vazio e adicionar itens:

const phoneBook = new Map();
phoneBook.set("Sally Smart", "555-9999");
phoneBook.set("John Doe", "555-1212");
phoneBook.set("J. Random Hacker", "553-1337");
Acesso por chave

O acesso a um elemento do mapa pode ser feito com o getmétodo:

const sallyNumber = phoneBook.get("Sally Smart");

Neste exemplo, o valor sallyNumberagora conterá a string "555-9999".

Enumeração

As chaves em um mapa são ordenadas. Assim, ao iterar por ele, um objeto de mapa retorna chaves na ordem de inserção. O seguinte demonstra a enumeração usando um loop for:

// loop through the collection and display each entry.
for (const [name, number] of phoneBook) {
    console.log(`Phone number for ${name} is ${number}`);
}

Uma chave pode ser removida da seguinte forma:

phoneBook.delete("Sally Smart");

Objeto

Um objeto é semelhante a um mapa - ambos permitem definir chaves para valores, recuperar esses valores, excluir chaves e detectar se um valor está armazenado em uma chave. Por esse motivo (e porque não havia alternativas embutidas), os objetos historicamente têm sido usados ​​como mapas.

No entanto, existem diferenças importantes que tornam um mapa preferível em certos casos. Em JavaScript, um objeto é um mapeamento de nomes de propriedades para valores, ou seja, uma matriz associativa com uma ressalva: as chaves de um objeto devem ser uma string ou um símbolo (objetos nativos e primitivos implicitamente convertidos em chaves de string são permitidos) . Os objetos também incluem um recurso não relacionado a matrizes associativas: um objeto tem um protótipo, portanto, contém chaves padrão que podem entrar em conflito com as chaves definidas pelo usuário. Portanto, fazer uma pesquisa por uma propriedade apontará a pesquisa para a definição do protótipo se o objeto não definir a propriedade.

Um literal de objeto é escrito como { property1: value1, property2: value2, ... }. Por exemplo:

const myObject = {
    "Sally Smart": "555-9999",
    "John Doe": "555-1212",
    "J. Random Hacker": "553-1337",
};

Para evitar que a pesquisa use as propriedades do protótipo, você pode usar a Object.setPrototypeOffunção:

Object.setPrototypeOf(myObject, null);

A partir do ECMAScript 5 (ES5), o protótipo também pode ser ignorado usando Object.create(null):

const myObject = Object.create(null);

Object.assign(myObject, {
    "Sally Smart": "555-9999",
    "John Doe": "555-1212",
    "J. Random Hacker": "553-1337",
});

Se o nome da propriedade for um identificador válido, as aspas podem ser omitidas, por exemplo:

const myOtherObject = { foo: 42, bar: false };

A pesquisa é escrita usando a notação de acesso à propriedade, colchetes, que sempre funcionam, ou notação de ponto, que só funciona para chaves identificadoras:

myObject["John Doe"]
myOtherObject.foo

Você também pode percorrer todas as propriedades enumeráveis ​​e valores associados da seguinte maneira (um loop for-in):

for (const property in myObject) {
    const value = myObject[property];
    console.log(`myObject[${property}] = ${value}`);
}

Ou (um loop for-of):

for (const [property, value] of Object.entries(myObject)) {
    console.log(`${property} = ${value}`);
}

Uma propriedade pode ser removida da seguinte forma:

delete myObject["Sally Smart"];

Como mencionado antes, as propriedades são strings e símbolos. Como cada objeto nativo e primitivo pode ser convertido implicitamente em uma string, você pode fazer:

myObject[1]                                        // key is "1"; note that myObject[1] == myObject["1"]
myObject[["a", "b"]]                               // key is "a,b"
myObject[{ toString() { return "hello world"; } }] // key is "hello world"

No JavaScript moderno, é considerado mau uso o tipo Array como um array associativo. O consenso é que o tipo de objectos e Map/ WeakMapaulas são os melhores para esta finalidade. O raciocínio por trás disso é que se Array for estendido por meio de protótipo e Object for mantido puro, os loops for e for-in funcionarão como esperado em 'arrays' associativos. Esse problema foi trazido à tona pela popularidade dos frameworks JavaScript que fazem uso pesado e às vezes indiscriminado de protótipos para estender os tipos embutidos do JavaScript.

Consulte JavaScript Array e Object Prototype Awareness Day para obter mais informações sobre o problema.

Julia

Em Julia , as seguintes operações gerenciam matrizes associativas.

Declarar dicionário:

 phonebook = Dict( "Sally Smart" => "555-9999", "John Doe" => "555-1212", "J. Random Hacker" => "555-1337" )

Elemento de acesso:

phonebook["Sally Smart"]

Adicionar elemento:

phonebook["New Contact"] = "555-2222"

Excluir elemento:

delete!(phonebook, "Sally Smart")

Obtenha chaves e valores como iteráveis :

keys(phonebook)
values(phonebook)

KornShell 93 e shells compatíveis

No KornShell 93 e em shells compatíveis (ksh93, bash4 ...), as seguintes operações podem ser usadas com matrizes associativas.

Definição:

 typeset -A phonebook; # ksh93
 declare -A phonebook; # bash4
 phonebook=(["Sally Smart"]="555-9999" ["John Doe"]="555-1212" ["[[J. Random Hacker]]"]="555-1337");

Desreferência:

 ${phonebook["John Doe"]};

Lisp

Lisp foi originalmente concebida como uma linguagem de "Processamento LISt", e um de seus tipos de dados mais importantes é a lista vinculada, que pode ser tratada como uma lista de associação ("alist").

'(("Sally Smart" . "555-9999")
  ("John Doe" . "555-1212")
  ("J. Random Hacker" . "553-1337"))

A sintaxe (x . y)é usada para indicar um par consed . Chaves e valores não precisam ser do mesmo tipo em uma lista. Lisp e Scheme fornecem operadores assocpara manipular listas de maneiras semelhantes a matrizes associativas.

Um conjunto de operações específicas para o tratamento de listas de associação existe para Common Lisp , cada uma delas funcionando de forma não destrutiva.

Para adicionar uma entrada a aconsfunção é empregada, criando e retornando uma nova lista de associações. Uma lista de associação no Common Lisp imita uma pilha, ou seja, adere ao princípio do último a entrar, primeiro a sair (LIFO) e, portanto, antecede o cabeçalho da lista.

(let ((phone-book NIL))
  (setf phone-book (acons "Sally Smart"      "555-9999" phone-book))
  (setf phone-book (acons "John Doe"         "555-1212" phone-book))
  (setf phone-book (acons "J. Random Hacker" "555-1337" phone-book)))

Esta função pode ser interpretada como uma acomodação para as consoperações.

;; The effect of
;;   (cons (cons KEY VALUE) ALIST)
;; is equivalent to
;;   (acons KEY VALUE ALIST)
(let ((phone-book '(("Sally Smart" . "555-9999") ("John Doe" . "555-1212"))))
  (cons (cons "J. Random Hacker" "555-1337") phone-book))

Obviamente, a pushoperação destrutiva também permite inserir entradas em uma lista de associação, uma entrada tendo que constituir um valor-chave contra para manter a validade do mapeamento.

(push (cons "Dummy" "123-4567") phone-book)

A pesquisa de uma entrada por sua chave é realizada por meio de assoc, que pode ser configurado para o predicado e direção de teste, especialmente pesquisando a lista de associações de sua extremidade à frente. O resultado, se positivo, retorna todas as desvantagens da entrada, não apenas seu valor. Falha em obter leds-chave correspondentes a um retorno do NILvalor.

(assoc "John Doe" phone-book :test #'string=)

Duas generalizações de assocexiste: assoc-ifespera uma função de predicado que testa a chave de cada entrada, retornando a primeira entrada para a qual o predicado produz um não- NILvalor na invocação. assoc-if-notinverte a lógica, aceitando os mesmos argumentos, mas retornando a primeira entrada gerada NIL.

;; Find the first entry whose key equals "John Doe".
(assoc-if
  #'(lambda (key)
      (string= key "John Doe"))
  phone-book)

;; Finds the first entry whose key is neither "Sally Smart" nor "John Doe"
(assoc-if-not
  #'(lambda (key)
      (member key '("Sally Smart" "John Doe") :test #'string=))
  phone-book)

O processo inverso, a detecção de uma entrada por seu valor, utiliza rassoc.

;; Find the first entry with a value of "555-9999".
;; We test the entry string values with the "string=" predicate.
(rassoc "555-9999" phone-book :test #'string=)

As generalizações correspondentes rassoc-ife rassoc-if-notexistem.

;; Finds the first entry whose value is "555-9999".
(rassoc-if
  #'(lambda (value)
      (string= value "555-9999"))
  phone-book)

;; Finds the first entry whose value is not "555-9999".
(rassoc-if-not
  #'(lambda (value)
      (string= value "555-9999"))
  phone-book)

Todas as funções de pesquisa de entrada anteriores podem ser substituídos por variantes gerais lista-centric, como find, find-if, find-if-not, bem como funções pertinentes como positione seus derivados.

;; Find an entry with the key "John Doe" and the value "555-1212".
(find (cons "John Doe" "555-1212") phone-book :test #'equal)

A eliminação, sem contrapartida específica, baseia-se nas facilidades da lista, incluindo as destrutivas.

;; Create and return an alist without any entry whose key equals "John Doe".
(remove-if
  #'(lambda (entry)
      (string= (car entry) "John Doe"))
  phone-book)

A iteração é realizada com o auxílio de qualquer função que espera uma lista.

;; Iterate via "map".
(map NIL
  #'(lambda (entry)
      (destructuring-bind (key . value) entry
        (format T "~&~s => ~s" key value)))
  phone-book)

;; Iterate via "dolist".
(dolist (entry phone-book)
  (destructuring-bind (key . value) entry
    (format T "~&~s => ~s" key value)))

Sendo listas estruturadas, operações de processamento e transformação podem ser aplicadas sem restrições.

;; Return a vector of the "phone-book" values.
(map 'vector #'cdr phone-book)

;; Destructively modify the "phone-book" via "map-into".
(map-into phone-book
  #'(lambda (entry)
      (destructuring-bind (key . value) entry
        (cons (reverse key) (reverse value))))
  phone-book)

Por causa de sua natureza linear, alists são usados ​​para conjuntos de dados relativamente pequenos. Common Lisp também oferece suporte a um tipo de dados de tabela de hash e, para Scheme, eles são implementados no SRFI 69. As tabelas de hash têm uma sobrecarga maior do que alists, mas fornecem acesso muito mais rápido quando há muitos elementos. Uma outra característica é o fato de que as tabelas hash Common Lisp não mantêm, ao contrário das listas de associação, a ordem de inserção da entrada.

Tabelas hash Lisp comuns são construídas por meio da make-hash-tablefunção, cujos argumentos abrangem, entre outras configurações, um predicado para testar a chave de entrada. Enquanto tolerar objetos arbitrários, mesmo heterogeneidade em uma única instância tabela hash, a especificação desta chave :testfunção se limita a entidades distintas: o padrão Common Lisp única exige o apoio de eq, eql, equal, e equalp, ainda designar operações adicionais ou personalizados como permissiva para betão implementações.

(let ((phone-book (make-hash-table :test #'equal)))
  (setf (gethash "Sally Smart"      phone-book) "555-9999")
  (setf (gethash "John Doe"         phone-book) "555-1212")
  (setf (gethash "J. Random Hacker" phone-book) "553-1337"))

A gethashfunção permite obter o valor associado a uma chave.

(gethash "John Doe" phone-book)

Além disso, um valor padrão para o caso de uma chave ausente pode ser especificado.

(gethash "Incognito" phone-book 'no-such-key)

Uma invocação de gethashrealmente retorna dois valores: o valor ou valor substituto para a chave e um indicador booleano, retornando Tse a tabela hash contém a chave e NILpara sinalizar sua ausência.

(multiple-value-bind (value contains-key) (gethash "Sally Smart" phone-book)
  (if contains-key
    (format T "~&The associated value is: ~s" value)
    (format T "~&The key could not be found.")))

Use remhashpara excluir a entrada associada a uma chave.

(remhash "J. Random Hacker" phone-book)

clrhash esvazia completamente a tabela de hash.

(clrhash phone-book)

A maphashfunção dedicada é especializada em iterar tabelas hash.

(maphash
  #'(lambda (key value)
      (format T "~&~s => ~s" key value))
  phone-book)

Alternativamente, a loopconstrução faz provisões para iterações, por meio de chaves, valores ou conjunções de ambos.

;; Iterate the keys and values of the hash table.
(loop
  for   key being the hash-keys of phone-book
  using (hash-value value)
  do    (format T "~&~s => ~s" key value))

;; Iterate the values of the hash table.
(loop
  for value being the hash-values of phone-book
  do  (print value))

Uma outra opção invoca with-hash-table-iterator, uma macro de criação de iterador, cujo processamento deve ser conduzido pelo chamador.

(with-hash-table-iterator (entry-generator phone-book)
  (loop do
    (multiple-value-bind (has-entry key value) (entry-generator)
      (if has-entry
        (format T "~&~s => ~s" key value)
        (loop-finish)))))

É fácil construir tipos de dados abstratos compostos em Lisp, usando estruturas ou recursos de programação orientada a objetos, em conjunto com listas, matrizes e tabelas de hash.

LPC

O LPC implementa matrizes associativas como um tipo fundamental conhecido como "mapa" ou "mapeamento", dependendo do driver. As chaves e valores podem ser de qualquer tipo. Um literal de mapeamento é escrito como ([ key_1 : value_1, key_2 : value_2 ]). O código procedural se parece com:

mapping phone_book = ([]);
phone_book["Sally Smart"] = "555-9999";
phone_book["John Doe"] = "555-1212";
phone_book["J. Random Hacker"] = "555-1337";

Os mapeamentos são acessados ​​para leitura usando o operador de indexação da mesma forma que para escrita, conforme mostrado acima. Assim, phone_book ["Sally Smart"] retornaria a string "555-9999", e phone_book ["John Smith"] retornaria 0. O teste de presença é feito usando a função member (), por exemploif(member(phone_book, "John Smith")) write("John Smith is listed.\n");

A exclusão é realizada usando uma função chamada m_delete () ou map_delete (), dependendo do driver: m_delete(phone_book, "Sally Smart");

Os drivers LPC da família Amylaar implementam mapeamentos multivalorados usando um índice numérico secundário (outros drivers da família MudOS não suportam mapeamentos multivalorados). Exemplo de sintaxe:

mapping phone_book = ([:2]);
phone_book["Sally Smart", 0] = "555-9999";
phone_book["Sally Smart", 1] = "99 Sharp Way";
phone_book["John Doe", 0] = "555-1212";
phone_book["John Doe", 1] = "3 Nigma Drive";
phone_book["J. Random Hacker", 0] = "555-1337";
phone_book["J. Random Hacker", 1] = "77 Massachusetts Avenue";

Os drivers LPC modernos o suficiente para suportar uma construção foreach () usam-no para iterar por meio de seus tipos de mapeamento.

Lua

Em Lua , "tabela" é um tipo fundamental que pode ser usado como um array (índice numérico, rápido) ou como um array associativo.

As chaves e valores podem ser de qualquer tipo, exceto nulo. O seguinte enfoca índices não numéricos.

Um literal de tabela é escrito como { value, key = value, [index] = value, ["non id string"] = value }. Por exemplo:

phone_book = {
	["Sally Smart"] = "555-9999", 
	["John Doe"] = "555-1212", 
	["J. Random Hacker"] = "553-1337", -- Trailing comma is OK
}

aTable = {
	-- Table as value
	subTable = { 5, 7.5, k = true }, -- key is "subTable"
	-- Function as value
	['John Doe'] = function (age) if age < 18 then return "Young" else return "Old!" end end,
	-- Table and function (and other types) can also be used as keys
}

Se a chave for um identificador válido (não uma palavra reservada), as aspas podem ser omitidas. Os identificadores são sensíveis a maiúsculas e minúsculas.

A pesquisa é escrita usando colchetes, que sempre funciona, ou notação de ponto, que funciona apenas para chaves identificadoras:

print(aTable["John Doe"](45))
x = aTable.subTable.k

Você também pode percorrer todas as chaves e valores associados com iteradores ou for-loops:

simple = { [true] = 1, [false] = 0, [3.14] = math.pi, x = 'x', ["!"] = 42 }
function FormatElement(key, value)
	return "[" .. tostring(key) .. "] = " .. value .. ", "
end
-- Iterate on all keys
table.foreach(simple, function (k, v) io.write(FormatElement(k, v)) end)
print""
for k, v in pairs(simple) do io.write(FormatElement(k, v)) end
print""
k= nil
repeat
	k, v = next(simple, k)
	if k ~= nil then io.write(FormatElement(k, v)) end
until k == nil
print""

Uma entrada pode ser removida definindo-a como nulo:

simple.x = nil

Da mesma forma, você pode substituir os valores ou adicioná-los:

simple['%'] = "percent"
simple['!'] = 111

Mathematica e Wolfram Language

Mathematica e Wolfram Language usam a expressão de associação para representar matrizes associativas.

 phonebook = <| "Sally Smart" -> "555-9999", 
                "John Doe" -> "555-1212",
                "J. Random Hacker" -> "553-1337" |>;

Acessar:

 phonebook[[Key["Sally Smart"]]]

Se as chaves são strings, a palavra-chave Key não é necessária, então:

 phonebook[["Sally Smart"]]

Para listar chaves: e valores

Keys[phonebook]
Values[phonebook]

CAXUMBA

No MUMPS, cada array é um array associativo. O suporte direto embutido em nível de idioma para matrizes associativas aplica-se a matrizes privadas específicas de processo armazenadas na memória chamadas "locais", bem como às matrizes permanentes, compartilhadas e globais armazenadas em disco que estão disponíveis simultaneamente para vários trabalhos . O nome para globais é precedido pelo circunflexo "^" para distingui-los das variáveis ​​locais.

SET ^phonebook("Sally Smart")="555-9999"      ;; storing permanent data
SET phonebook("John Doe")="555-1212"          ;; storing temporary data
SET phonebook("J. Random Hacker")="553-1337"  ;; storing temporary data
MERGE ^phonebook=phonebook                    ;; copying temporary data into permanent data

Para acessar o valor de um elemento, basta usar o nome com o subscrito:

WRITE "Phone Number :",^phonebook("Sally Smart"),!

Você também pode percorrer uma matriz associada da seguinte maneira:

SET NAME=""
FOR  S NAME=$ORDER(^phonebook(NAME)) QUIT:NAME=""  WRITE NAME,"  Phone Number :",^phonebook(NAME),!

Objective-C (Cocoa / GNUstep)

Cocoa e GNUstep , escritos em Objective-C , lidam com matrizes associativas usando NSMutableDictionary(uma versão mutável de NSDictionary) cluster de classe. Esta classe permite atribuições entre quaisquer dois objetos. Uma cópia do objeto da chave é feita antes de ser inserido NSMutableDictionary, portanto, as chaves devem estar em conformidade com o NSCopyingprotocolo. Ao ser inserido em um dicionário, o objeto de valor recebe uma mensagem reter para aumentar sua contagem de referência. O objeto de valor receberá a mensagem de liberação quando for excluído do dicionário (explicitamente ou adicionando ao dicionário um objeto diferente com a mesma chave).

NSMutableDictionary *aDictionary = [[NSMutableDictionary alloc] init];
[aDictionary setObject:@"555-9999" forKey:@"Sally Smart"]; 
[aDictionary setObject:@"555-1212" forKey:@"John Doe"]; 
[aDictionary setObject:@"553-1337" forKey:@"Random Hacker"];

Para acessar os objetos atribuídos, este comando pode ser usado:

id anObject = [aDictionary objectForKey:@"Sally Smart"];

Todas as chaves ou valores podem ser enumerados usando NSEnumerator:

NSEnumerator *keyEnumerator = [aDictionary keyEnumerator];
id key;
while ((key = [keyEnumerator nextObject]))
{
  // ... process it here ...
}

No Mac OS X 10.5+ e no iPhone OS, as chaves de dicionário podem ser enumeradas de forma mais concisa usando a NSFastEnumerationconstrução:

for (id key in aDictionary) {
  // ... process it here ...
}

O que é ainda mais prático, gráficos de dados estruturados podem ser facilmente criados usando Cocoa , especialmente NSDictionary( NSMutableDictionary). Isso pode ser ilustrado com este exemplo compacto:

NSDictionary *aDictionary =
       [NSDictionary dictionaryWithObjectsAndKeys:
                           [NSDictionary dictionaryWithObjectsAndKeys:
                                   @"555-9999", @"Sally Smart",
                                   @"555-1212", @"John Doe",
                                   nil], @"students",
                           [NSDictionary dictionaryWithObjectsAndKeys:
                                   @"553-1337", @"Random Hacker",
                                   nil], @"hackers",
                           nil];

Os campos relevantes podem ser acessados ​​rapidamente usando caminhos-chave:

id anObject = [aDictionary valueForKeyPath:@"students.Sally Smart"];

OCaml

A linguagem de programação OCaml fornece três contêineres associativos diferentes. O mais simples é uma lista de pares:

# let m = [
	"Sally Smart", "555-9999";
	"John Doe", "555-1212";
	"J. Random Hacker", "553-1337"];;
val m : (string * string) list = [
	("Sally Smart", "555-9999");
	("John Doe", "555-1212");
	("J. Random Hacker", "553-1337")
]
# List.assoc "John Doe" m;;
- : string = "555-1212"

A segunda é uma tabela hash polimórfica:

# let m = Hashtbl.create 3;;
val m : ('_a, '_b) Hashtbl.t = <abstr>
# Hashtbl.add m "Sally Smart" "555-9999";
  Hashtbl.add m "John Doe" "555-1212";
  Hashtbl.add m "J. Random Hacker" "553-1337";;
- : unit = ()
# Hashtbl.find m "John Doe";;
- : string = "555-1212"

O código acima usa a função hash padrão do OCaml Hashtbl.hash, que é definida automaticamente para todos os tipos. Para usar uma função hash modificada, use a interface do functor Hashtbl.Makepara criar um módulo, como com Map.

Finalmente, mapas funcionais (representados como árvores binárias balanceadas imutáveis):

# module StringMap = Map.Make(String);;
...
# let m = StringMap.add "Sally Smart" "555-9999" StringMap.empty
  let m = StringMap.add "John Doe" "555-1212" m
  let m = StringMap.add "J. Random Hacker" "553-1337" m;;
val m : string StringMap.t = <abstr>
# StringMap.find "John Doe" m;;
 - : string = "555-1212"

Observe que, para usar Map, você deve fornecer ao functor Map.Makeum módulo que define o tipo de chave e a função de comparação. A biblioteca de terceiros ExtLib fornece uma versão polimórfica de mapas funcionais, chamados PMap, que recebem uma função de comparação na criação.

Listas de pares e mapas funcionais fornecem uma interface puramente funcional. Por outro lado, as tabelas de hash fornecem uma interface imperativa. Para muitas operações, as tabelas hash são significativamente mais rápidas do que listas de pares e mapas funcionais.

OptimJ

A linguagem de programação OptimJ é uma extensão do Java 5. Assim como o Java, o Optimj fornece mapas; mas OptimJ também fornece matrizes associativas verdadeiras. As matrizes Java são indexadas com inteiros não negativos; matrizes associativas são indexadas com qualquer tipo de chave.

String[String] phoneBook = {
"Sally Smart"      -> "555-9999",
"John Doe"         -> "555-1212",
"J. Random Hacker" -> "553-1337"
};

// String[String] is not a java type but an optimj type:
// associative array of strings indexed by strings.

// iterate over the values
for(String number : phoneBook) {
System.out.println(number);
}

// The previous statement prints:  "555-9999" "555-1212" "553-1337"

// iterate over the keys
for(String name : phoneBook.keys) {
System.out.println(name + " -> " + phoneBook[name]);
}
// phoneBook[name] access a value by a key (it looks like java array access)
// i.e. phoneBook["John Doe"] returns "555-1212"

Obviamente, é possível definir arrays multidimensionais, misturar arrays Java e arrays associativos, misturar mapas e arrays associativos.

 int[String][][double] a;
 java.util.Map<String[Object], Integer> b;

Perl 5

Perl 5 possui suporte embutido em nível de linguagem para matrizes associativas. Perl moderno se refere a matrizes associativas como hashes ; o termo matriz associativa é encontrado em documentação mais antiga, mas é considerado um tanto arcaico. Os hashes Perl 5 são simples: as chaves são strings e os valores são escalares. No entanto, os valores podem ser referências a matrizes ou outros hashes, e o módulo Perl 5 padrão Tie :: RefHash permite que os hashes sejam usados ​​com chaves de referência.

Uma variável hash é marcada por um % sigilo , para distingui-la de escalar, array e outros tipos de dados. Um literal de hash é uma lista de valores-chave, com a forma preferencial usando =>token de Perl , que é semanticamente idêntico à vírgula e torna a associação de valores-chave mais clara:

my %phone_book = (
	'Sally Smart'      => '555-9999',
	'John Doe'         => '555-1212',
	'J. Random Hacker' => '553-1337',
);

O acesso a um elemento hash usa a sintaxe $hash_name{$key}- a chave é cercada por chaves e o nome do hash é prefixado por um $, indicando que o próprio elemento hash é um valor escalar, embora seja parte de um hash. O valor de $phone_book{'John Doe'}é '555-1212'. O %sigilo é usado apenas quando se refere ao hash como um todo, como ao pedir keys %phone_book.

A lista de chaves e valores podem ser extraídos usando as funções internas keyse values, respectivamente. Então, por exemplo, para imprimir todas as chaves de um hash:

foreach $name (keys %phone_book) {
	print $name, "\n";
}

Pode-se iterar por meio de pares (chave, valor) usando a eachfunção:

while (($name, $number) = each %phone_book) {
	print 'Number for ', $name, ': ', $number, "\n";
}

Uma "referência" de hash, que é um valor escalar que aponta para um hash, é especificada na forma literal usando chaves como delimitadores, com sintaxe semelhante à especificação de um literal de hash:

my $phone_book = {
	'Sally Smart' => '555-9999',
	'John Doe' => '555-1212',
	'J. Random Hacker' => '553-1337',
};

Os valores em uma referência de hash são acessados ​​usando o operador de desreferenciamento:

print $phone_book->{'Sally Smart'};

Quando o hash contido na referência de hash precisa ser referido como um todo, como keysacontece com a função, a sintaxe é a seguinte:

foreach $name (keys %{$phone_book}) {
	print 'Number for ', $name, ': ', $phone_book->{$name}, "\n";
}

Perl 6 (Raku)

Perl 6 , renomeado como "Raku", também possui suporte embutido em nível de linguagem para matrizes associativas, que são chamadas de hashes ou objetos que desempenham a função "associativa". Como no Perl 5, os hashes padrão do Perl 6 são simples: as chaves são strings e os valores são escalares. Pode-se definir um hash para não forçar todas as chaves para strings automaticamente: eles são referidos como "hashes de objeto", porque as chaves de tais hashes permanecem o objeto original ao invés de uma stringificação dele.

Uma variável hash é tipicamente marcada por um % sigilo , para distingui-la visualmente do escalar, array e outros tipos de dados, e para definir seu comportamento em relação à iteração. Um literal de hash é uma lista de valores-chave, com a forma preferencial usando =>token de Perl , o que torna a associação de valores-chave mais clara:

my %phone-book =
	'Sally Smart'      => '555-9999',
	'John Doe'         => '555-1212',
	'J. Random Hacker' => '553-1337',
;

Acessar um elemento hash usa a sintaxe %hash_name{$key}- a chave é cercada por chaves e o nome do hash (observe que o sigilo não muda, ao contrário do Perl 5). O valor de %phone-book{'John Doe'}é '555-1212'.

A lista de chaves e valores podem ser extraídos usando as funções internas keyse values, respectivamente. Então, por exemplo, para imprimir todas as chaves de um hash:

for %phone-book.keys -> $name {
	say $name;
}

Por padrão, ao iterar por meio de um hash, obtém-se pares de valores-chave.

for %phone-book -> $entry {
	say "Number for $entry.key(): $entry.value()";  # using extended interpolation features
}

Também é possível obter valores-chave e valores de valor alternados usando o kvmétodo:

for %phone-book.kv -> $name, $number {
	say "Number for $name: $number";
}

Raku não tem nenhuma referência. Hashes podem ser passados ​​como parâmetros únicos que não são nivelados. Se você quiser ter certeza de que uma sub-rotina só aceita hashes, use % sigil na assinatura.

sub list-phone-book(%pb) {
    for %pb.kv -> $name, $number {
        say "Number for $name: $number";
    }
}
list-phone-book(%phone-book);

Em conformidade com a digitação gradual , os hashes podem estar sujeitos a restrições de tipo, confinando um conjunto de chaves válidas a um determinado tipo.

# Define a hash whose keys may only be integer numbers ("Int" type).
my %numbersWithNames{Int};

# Keys must be integer numbers, as in this case.
%numbersWithNames.push(1 => "one");

# This will cause an error, as strings as keys are invalid.
%numbersWithNames.push("key" => "two");

PHP

O tipo de array embutido do PHP é, na realidade, um array associativo. Mesmo ao usar índices numéricos, o PHP armazena internamente arrays como arrays associativos. Portanto, o PHP pode ter matrizes indexadas numericamente não consecutivamente. As chaves devem ser inteiras (números de ponto flutuante são truncados para inteiros) ou tipo string, enquanto os valores podem ser de tipos arbitrários, incluindo outros arrays e objetos. Os arrays são heterogêneos: um único array pode ter chaves de diferentes tipos. Os arrays associativos do PHP podem ser usados ​​para representar árvores, listas, pilhas, filas e outras estruturas de dados comuns não incorporadas ao PHP.

Uma matriz associativa pode ser declarada usando a seguinte sintaxe:

$phonebook                     = array();
$phonebook['Sally Smart']      = '555-9999';
$phonebook['John Doe']         = '555-1212';
$phonebook['J. Random Hacker'] = '555-1337';

// or

$phonebook = array(
    'Sally Smart'      => '555-9999',
    'John Doe'         => '555-1212',
    'J. Random Hacker' => '555-1337',
);

// or, as of PHP 5.4

$phonebook = [
    'Sally Smart'      => '555-9999',
    'John Doe'         => '555-1212',
    'J. Random Hacker' => '555-1337',
];

// or

$phonebook['contacts']['Sally Smart']['number']      = '555-9999';
$phonebook['contacts']['John Doe']['number']         = '555-1212';
$phonebook['contacts']['J. Random Hacker']['number'] = '555-1337';

O PHP pode fazer um loop em uma matriz associativa da seguinte maneira:

foreach ($phonebook as $name => $number) {
    echo 'Number for ', $name, ': ', $number, "\n";
}

// For the last array example it is used like this
foreach ($phonebook['contacts'] as $name => $num) {
   echo 'Name: ', $name, ', number: ', $num['number'], "\n";
}

O PHP possui um amplo conjunto de funções para operar em matrizes.

Matrizes associativas que podem usar objetos como chaves, em vez de strings e inteiros, podem ser implementadas com a SplObjectStorageclasse da Biblioteca PHP padrão (SPL).

Pique

Pike tem suporte integrado para matrizes associativas, conhecidas como mapeamentos. Os mapeamentos são criados da seguinte forma:

mapping(string:string) phonebook = ([
	"Sally Smart":"555-9999",
	"John Doe":"555-1212",
	"J. Random Hacker":"555-1337"
]);

O acesso e o teste de presença em mapeamentos são feitos usando o operador de indexação. Então phonebook["Sally Smart"], retornaria a string "555-9999"e phonebook["John Smith"]retornaria 0.

A iteração por meio de um mapeamento pode ser feita usando foreach:

foreach(phonebook; string key; string value) {
	write("%s:%s\n", key, value);
}

Ou usando um objeto iterador:

Mapping.Iterator i = get_iterator(phonebook);
while (i->index()) {
	write("%s:%s\n", i->index(), i->value());
	i->next();
}

Os elementos de um mapeamento podem ser removidos usando m_delete, que retorna o valor do índice removido:

string sallys_number = m_delete(phonebook, "Sally Smart");

PostScript

Em PostScript , as matrizes associativas são chamadas de dicionários. No PostScript de nível 1, eles devem ser criados explicitamente, mas o nível 2 introduziu a declaração direta usando uma sintaxe de colchetes de ângulo duplo:

  % Level 1 declaration
  3 dict dup begin
    /red   (rouge) def
    /green (vert)  def
    /blue  (bleu)  def
  end

  % Level 2 declaration
  <<
    /red   (rot)
    /green (gruen)
    /blue  (blau)
  >>

  % Both methods leave the dictionary on the operand stack

Os dicionários podem ser acessados ​​diretamente, usando get, ou implicitamente, colocando o dicionário na pilha de dicionários usando begin:

  % With the previous two dictionaries still on the operand stack
  /red get print    % outputs 'rot'

  begin
  green print       % outputs 'vert'
  end

O conteúdo do dicionário pode ser iterado usando forall, embora não em uma ordem específica:

  % Level 2 example
  <<
    /This  1
    /That  2
    /Other 3
  >> {exch =print ( is ) print ==} forall

O que pode resultar em:

  That is 2
  This is 1
  Other is 3

Os dicionários podem ser aumentados (até seu tamanho definido apenas no Nível 1) ou alterados usando put, e as entradas podem ser removidas usando undef:

  % define a dictionary for easy reuse:
  /MyDict <<
    /rouge (red)
    /vert (gruen)
  >> def

  % add to it
  MyDict /bleu (blue) put

  % change it
  MyDict /vert (green) put

  % remove something
  MyDict /rouge undef

Prolog

Algumas versões do Prolog incluem utilitários de dicionário ("dict").

Pitão

Em Python , os arrays associativos são chamados de " dicionários ". Literais de dicionário são delimitados por chaves:

phonebook = {
    "Sally Smart": "555-9999",
    "John Doe": "555-1212",
    "J. Random Hacker": "553-1337",
}

Para acessar uma entrada em Python, basta usar o operador de indexação de matriz:

>>> phonebook["Sally Smart"]
'555-9999'

Loop iterando por todas as chaves do dicionário:

>>> for key in phonebook:
...     print(key, phonebook[key])
Sally Smart 555-9999
J. Random Hacker 553-1337
John Doe 555-1212

Iterando por meio de tuplas (chave, valor):

>>> for key, value in phonebook.items():
...     print(key, value)
Sally Smart 555-9999
J. Random Hacker 553-1337
John Doe 555-1212

As chaves do dicionário podem ser excluídas individualmente usando a delinstrução. O valor correspondente pode ser retornado antes que o par de valores-chave seja excluído usando o método "pop" do tipo "dict":

>>> del phonebook["John Doe"]
>>> val = phonebook.pop("Sally Smart")
>>> phonebook.keys() # Only one key left
['J. Random Hacker']

Python 2.7 e 3.x também suportam compreensão de lista de dicionário , uma sintaxe compacta para gerar um dicionário a partir de qualquer iterador:

>>> square_dict = {i: i*i for i in range(5)}
>>> square_dict
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
>>> {key: value for key, value in phonebook.items() if "J" in key}
{'J. Random Hacker': '553-1337', 'John Doe': '555-1212'}

Estritamente falando, um dicionário é um superconjunto de uma matriz associativa, uma vez que nem as chaves ou valores são limitados a um único tipo de dados. Pode-se pensar em um dicionário como uma "lista associativa" usando a nomenclatura do Python. Por exemplo, o seguinte também é legítimo:

phonebook = {
    "Sally Smart": "555-9999",
    "John Doe": None,
    "J. Random Hacker": -3.32,
    14: "555-3322",
}

As chaves do dicionário devem ser de um tipo de dados imutável . Em Python, as strings são imutáveis ​​devido ao seu método de implementação.

vermelho

Em vermelho, o map!tipo de dados integrado fornece uma matriz associativa que mapeia valores de palavra, string e tipos de chave escalar para valores de qualquer tipo. Uma tabela hash é usada internamente para pesquisa.

Um mapa pode ser escrito como literal, como #(key1 value1 key2 value2 ...), ou pode ser criado usando make map! [key1 value1 key2 value2 ...]:

Red [Title:"My map"]

my-map: make map! [
    "Sally Smart"      "555-9999"
    "John Doe"         "555-1212"
    "J. Random Hacker" "553-1337"
]

; Red preserves case for both keys and values, however lookups are case insensitive by default; it is possible to force case sensitivity using the <code>/case</code> refinement for <code>select</code> and <code>put</code>.

; It is of course possible to use <code>word!</code> values as keys, in which case it is generally preferred to use <code>set-word!</code> values when creating the map, but any word type can be used for lookup or creation.

my-other-map: make map! [foo: 42 bar: false]

; Notice that the block is not reduced or evaluated in any way, therefore in the above example the key <code>bar</code> is associated with the <code>word!</code> <code>false</code> rather than the <code>logic!</code> value false; literal syntax can be used if the latter is desired:

my-other-map: make map! [foo: 42 bar: #[false]]

; or keys can be added after creation:

my-other-map: make map! [foo: 42]
my-other-map/bar: false

; Lookup can be written using <code>path!</code> notation or using the <code>select</code> action:

select my-map "Sally Smart"
my-other-map/foo

; You can also loop through all keys and values with <code>foreach</code>:

foreach [key value] my-map [
    print [key "is associated to" value]
]

; A key can be removed using <code>remove/key</code>:

remove/key my-map "Sally Smart"

REXX

No REXX , as matrizes associativas são chamadas de "variáveis-tronco" ou "Variáveis ​​compostas".

KEY = 'Sally Smart'
PHONEBOOK.KEY = '555-9999'
KEY = 'John Doe'
PHONEBOOK.KEY = '555-1212'
KEY = 'J. Random Hacker'
PHONEBOOK.KEY = '553-1337'

Variáveis-tronco com teclas numéricas normalmente começam em 1 e aumentam a partir daí. A variável raiz de chave 0 por convenção contém o número total de itens na raiz:

NAME.1 = 'Sally Smart'
NAME.2 = 'John Doe'
NAME.3 = 'J. Random Hacker'
NAME.0 = 3

O REXX não tem uma maneira fácil de acessar automaticamente as chaves de uma variável radical; e normalmente as chaves são armazenadas em uma matriz associativa separada, com teclas numéricas.

Rubi

Em Ruby, uma tabela hash é usada da seguinte maneira:

irb(main):001:0> phonebook = {
irb(main):002:1* 'Sally Smart' => '555-9999',
irb(main):003:1* 'John Doe' => '555-1212',
irb(main):004:1* 'J. Random Hacker' => '553-1337'
irb(main):005:1> }
=> {"Sally Smart"=>"555-9999", "John Doe"=>"555-1212", "J. Random Hacker"=>"553-1337"}
irb(main):006:0> phonebook['John Doe']
=> "555-1212"

Ruby oferece suporte a looping de hash e iteração com a seguinte sintaxe:

irb(main):007:0> ### iterate over keys and values
irb(main):008:0* phonebook.each {|key, value| puts key + " => " + value}
Sally Smart => 555-9999
John Doe => 555-1212
J. Random Hacker => 553-1337
=> {"Sally Smart"=>"555-9999", "John Doe"=>"555-1212", "J. Random Hacker"=>"553-1337"}
irb(main):009:0> ### iterate keys only
irb(main):010:0* phonebook.each_key {|key| puts key}
Sally Smart
John Doe
J. Random Hacker
=> {"Sally Smart"=>"555-9999", "John Doe"=>"555-1212", "J. Random Hacker"=>"553-1337"}
irb(main):011:0> ### iterate values only
irb(main):012:0* phonebook.each_value {|value| puts value}
555-9999
555-1212
553-1337
=> {"Sally Smart"=>"555-9999", "John Doe"=>"555-1212", "J. Random Hacker"=>"553-1337"}

Ruby também suporta muitas outras operações úteis em hashes, como mesclar hashes, selecionar ou rejeitar elementos que atendem a alguns critérios, inverter (trocar as chaves e valores) e simplificar um hash em um array.

Ferrugem

A biblioteca padrão Rust fornece um mapa hash ( std::collections::HashMap) e um mapa de árvore B ( std::collections::BTreeMap). Eles compartilham vários métodos com os mesmos nomes, mas têm requisitos diferentes para os tipos de chaves que podem ser inseridas. O HashMaprequer chaves para implementar as características Eq( relação de equivalência ) e Hash(hashabilidade) e armazena as entradas em uma ordem não especificada, e BTreeMaprequer a característica Ord( ordem total ) para suas chaves e armazena as entradas em uma ordem definida pelo tipo de chave. A ordem é refletida pelos iteradores padrão.

use std::collections::HashMap;
let mut phone_book = HashMap::new();
phone_book.insert("Sally Smart", "555-9999");
phone_book.insert("John Doe", "555-1212");
phone_book.insert("J. Random Hacker", "555-1337");

Os iteradores padrão visitam todas as entradas como tuplas. Os HashMapiteradores visitam as entradas em uma ordem não especificada e o BTreeMapiterador visita as entradas na ordem definida pelo tipo de chave.

for (name, number) in &phone_book {
    println!("{} {}", name, number);
}

Também existe um iterador para as chaves:

for name in phone_book.keys() {
    println!("{}", name);
}

Gíria

S-Lang tem um tipo de matriz associativa:

phonebook = Assoc_Type[];
phonebook["Sally Smart"] = "555-9999"
phonebook["John Doe"] = "555-1212"
phonebook["J. Random Hacker"] = "555-1337"

Você também pode percorrer uma matriz associada de várias maneiras:

foreach name (phonebook) {
	vmessage ("%s %s", name, phonebook[name]);
}

Para imprimir uma lista classificada, é melhor aproveitar as vantagens do forte suporte da S-lang para matrizes padrão:

keys = assoc_get_keys(phonebook);
i = array_sort(keys);
vals = assoc_get_values(phonebook);
array_map (Void_Type, &vmessage, "%s %s", keys[i], vals[i]);

Scala

Scala fornece uma Mapclasse imutável como parte da scala.collectionestrutura:

val phonebook = Map("Sally Smart" -> "555-9999",
  "John Doe" -> "555-1212",
  "J. Random Hacker" -> "553-1337")

A inferência de tipo de Scala decidirá que este é um Map[String, String]. Para acessar a matriz:

phonebook.get("Sally Smart")

Isso retorna um Optiontipo, o equivalente em Scala da mônada Maybe em Haskell.

Conversa fiada

Em Smalltalk, a Dictionaryé usado:

phonebook := Dictionary new.
phonebook at: 'Sally Smart' put: '555-9999'.
phonebook at: 'John Doe' put: '555-1212'.
phonebook at: 'J. Random Hacker' put: '553-1337'.

Para acessar uma entrada, a mensagem #at:é enviada ao objeto de dicionário:

phonebook at: 'Sally Smart'

Que dá:

 '555-9999'

Um dicionário faz hashes, ou compara, com base na igualdade e marca a chave e o valor como referências fortes . Existem variantes nas quais hash / compare na identidade (IdentityDictionary) ou mantém referências fracas (WeakKeyDictionary / WeakValueDictionary). Como todo objeto implementa #hash, qualquer objeto pode ser usado como chave (e, claro, também como valor).

SNOBOL

SNOBOL é uma das primeiras (se não a primeira) linguagens de programação a usar matrizes associativas. As matrizes associativas no SNOBOL são chamadas de tabelas.

PHONEBOOK = TABLE()
PHONEBOOK['Sally Smart'] = '555-9999'
PHONEBOOK['John Doe'] = '555-1212'
PHONEBOOK['J. Random Hacker'] = '553-1337'

ML padrão

O padrão SML'97 da linguagem de programação Standard ML não fornece nenhum contêiner associativo. No entanto, várias implementações de ML padrão fornecem contêineres associativos.

A biblioteca da implementação popular do Standard ML de New Jersey (SML / NJ) fornece uma assinatura (algo como uma "interface") ORD_MAP, que define uma interface comum para matrizes associativas funcionais ordenadas (imutáveis). Existem vários functors- geral BinaryMapFn, ListMapFn, RedBlackMapFn, e SplayMapFn-que permitem criar o tipo correspondente de mapa ordenado (os tipos são uma árvore de auto-equilíbrio binário busca , ordenada lista de associação , árvore de vermelho-preto e árvore splay , respectivamente), utilizando uma estrutura fornecida pelo usuário para descrever o tipo de chave e o comparador. O functor retorna uma estrutura de acordo com a ORD_MAPinterface. Além disso, existem dois módulos predefinidos para matrizes associativas que empregam chaves inteiras: IntBinaryMape IntListMap.

- structure StringMap = BinaryMapFn (struct
                                       type ord_key = string
                                       val compare = String.compare
                                     end);
structure StringMap : ORD_MAP

- val m = StringMap.insert (StringMap.empty, "Sally Smart", "555-9999")
  val m = StringMap.insert (m, "John Doe", "555-1212")
  val m = StringMap.insert (m, "J. Random Hacker", "553-1337");
val m =
  T
    {cnt=3,key="John Doe",
     left=T {cnt=1,key="J. Random Hacker",left=E,right=E,value="553-1337"},
     right=T {cnt=1,key="Sally Smart",left=E,right=E,value="555-9999"},
     value="555-1212"} : string StringMap.map
- StringMap.find (m, "John Doe");
val it = SOME "555-1212" : string option

SML / NJ também fornece uma tabela hash polimórfica:

- exception NotFound;
exception NotFound
- val m : (string, string) HashTable.hash_table = HashTable.mkTable (HashString.hashString, op=) (3, NotFound);
val m =
  HT
    {eq_pred=fn,hash_fn=fn,n_items=ref 0,not_found=NotFound(-),
     table=ref [|NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,...|]}
  : (string,string) HashTable.hash_table
- HashTable.insert m ("Sally Smart", "555-9999");
val it = () : unit
- HashTable.insert m ("John Doe", "555-1212");
val it = () : unit
- HashTable.insert m ("J. Random Hacker", "553-1337");
val it = () : unit
HashTable.find m "John Doe"; (* returns NONE if not found *)
val it = SOME "555-1212" : string option
- HashTable.lookup m "John Doe"; (* raises the exception if not found *)
val it = "555-1212" : string

Tabelas hash monomórficas também são suportadas, usando o HashTableFnfunctor.

Outra implementação de ML padrão, Moscow ML , também fornece alguns contêineres associativos. Primeiro, ele fornece tabelas de hash polimórficas na Polyhashestrutura. Além disso, alguns mapas funcionais da biblioteca SML / NJ acima estão disponíveis como Binarymap, Splaymape Intmapestruturas.

Tcl

Existem dois recursos Tcl que oferecem suporte à semântica de matriz associativa. Um "array" é uma coleção de variáveis. Um "dict" é uma implementação completa de matrizes associativas.

variedade

set {phonebook(Sally Smart)} 555-9999
set john {John Doe}
set phonebook($john) 555-1212
set {phonebook(J. Random Hacker)} 553-1337

Se houver um caractere de espaço no nome da variável, o nome deve ser agrupado usando colchetes (nenhuma substituição realizada) ou aspas duplas (substituição realizada).

Como alternativa, vários elementos da matriz podem ser definidos por um único comando, apresentando seus mapeamentos como uma lista (palavras que contêm espaços em branco são colchetes):

array set phonebook [list {Sally Smart} 555-9999 {John Doe} 555-1212 {J. Random Hacker} 553-1337]

Para acessar uma entrada de matriz e colocá-la na saída padrão:

puts $phonebook(Sally\ Smart)

Que retorna este resultado:

555-9999

Para recuperar a matriz inteira como um dicionário:

array get phonebook

O resultado pode ser (a ordem das chaves não é especificada, não porque o dicionário esteja desordenado, mas porque a matriz está):

{Sally Smart} 555-9999 {J. Random Hacker} 553-1337 {John Doe} 555-1212

dict

set phonebook [dict create {Sally Smart} 555-9999 {John Doe} 555-1212 {J. Random Hacker} 553-1337]

Para procurar um item:

dict get $phonebook {John Doe}

Para iterar por meio de um dict:

foreach {name number} $phonebook {
	puts "name: $name\nnumber: $number"
}

Visual básico

O Visual Basic pode usar a classe Dictionary do Microsoft Scripting Runtime (que acompanha o Visual Basic 6). Não há implementação padrão comum a todas as versões:

' Requires a reference to SCRRUN.DLL in Project Properties
Dim phoneBook As New Dictionary
phoneBook.Add "Sally Smart", "555-9999"
phoneBook.Item("John Doe") = "555-1212"
phoneBook("J. Random Hacker") = "553-1337"
For Each name In phoneBook
	MsgBox name & " = " & phoneBook(name)
Next

Visual Basic .NET

O Visual Basic .NET usa as classes de coleção fornecidas pelo .NET Framework .

Criação

O código a seguir demonstra a criação e o preenchimento de um dicionário (consulte o exemplo C # nesta página para obter informações adicionais):

Dim dic As New System.Collections.Generic.Dictionary(Of String, String)
dic.Add("Sally Smart", "555-9999")
dic("John Doe") = "555-1212"
dic.Item("J. Random Hacker") = "553-1337"

Uma sintaxe alternativa seria usar um inicializador de coleção , que compila para chamadas individuais para Add:

Dim dic As New System.Collections.Dictionary(Of String, String) From {
    {"Sally Smart", "555-9999"},
    {"John Doe", "555-1212"},
    {"J. Random Hacker", "553-1337"}
}

Acesso por chave

Exemplo de demonstração de acesso (consulte acesso C # ):

Dim sallyNumber = dic("Sally Smart")
' or
Dim sallyNumber = dic.Item("Sally Smart")
Dim result As String = Nothing
Dim sallyNumber = If(dic.TryGetValue("Sally Smart", result), result, "n/a")

Enumeração

Exemplo de demonstração de enumeração (consulte # enumeração C # ):

' loop through the collection and display each entry.
For Each kvp As KeyValuePair(Of String, String) In dic
    Console.WriteLine("Phone number for {0} is {1}", kvp.Key, kvp.Value)
Next

Windows PowerShell

Ao contrário de muitos outros interpretadores de linha de comando , o Windows PowerShell tem suporte integrado em nível de linguagem para definir matrizes associativas:

$phonebook = @{
        'Sally Smart' = '555-9999';
	'John Doe' = '555-1212'; 
	'J. Random Hacker' = '553-1337'
}

Como em JavaScript, se o nome da propriedade for um identificador válido, as aspas podem ser omitidas:

$myOtherObject = @{ foo = 42; bar = $false }

As entradas podem ser separadas por ponto-e-vírgula ou uma nova linha:

$myOtherObject = @{ foo = 42
                    bar = $false ;
                    zaz = 3
}

Chaves e valores podem ser qualquer tipo de objeto .NET :

$now = [DateTime]::Now
$tomorrow = $now.AddDays(1)
$ProcessDeletionSchedule = @{ 
        (Get-Process notepad) = $now 
        (Get-Process calc) = $tomorrow
}

Também é possível criar uma matriz associativa vazia e adicionar entradas únicas, ou mesmo outras matrizes associativas, a ela mais tarde:

$phonebook = @{}
$phonebook += @{ 'Sally Smart' = '555-9999' }
$phonebook += @{ 'John Doe' = '555-1212'; 'J. Random Hacker' = '553-1337' }

Novas entradas também podem ser adicionadas usando o operador de índice de matriz, o operador de propriedade ou o Add()método do objeto .NET subjacente:

$phonebook = @{}
$phonebook['Sally Smart'] = '555-9999'
$phonebook.'John Doe' = '555-1212'
$phonebook.Add('J. Random Hacker', '553-1337')

Para cancelar a referência de objetos atribuídos, o operador de índice de matriz, o operador de propriedade ou a propriedade parametrizada Item()do objeto .NET pode ser usado:

$phonebook['Sally Smart'] 
$phonebook.'John Doe'
$phonebook.Item('J. Random Hacker')

Você pode fazer um loop em uma matriz associativa da seguinte maneira:

$phonebook.Keys | foreach { "Number for {0}: {1}" -f $_,$phonebook.$_ }

Uma entrada pode ser removida usando o Remove()método do objeto .NET subjacente:

$phonebook.Remove('Sally Smart')

As tabelas de hash podem ser adicionadas:

$hash1 = @{ a=1; b=2 }
$hash2 = @{ c=3; d=4 }
$hash3 = $hash1 + $hash2

Suporte a formatos de serialização de dados

Muitos formatos de serialização de dados também oferecem suporte a matrizes associativas (consulte esta tabela )

JSON

Em JSON , as matrizes associativas também são chamadas de objetos. As chaves só podem ser strings.

{
    "Sally Smart": "555-9999",
    "John Doe": "555-1212",
    "J. Random Hacker": "555-1337"
}

YAML

As matrizes associativas YAML também são chamadas de elementos de mapa ou pares de valor-chave. YAML não impõe restrições aos tipos de chaves; em particular, eles não estão restritos a serem valores escalares ou de string.

Sally Smart: 555-9999
John Doe: 555-1212
J. Random Hacker: 555-1337

Referências