Jump to content

Сравнение языков программирования (ассоциативный массив)

В этом сравнении языков программирования (ассоциативных массивов) сравниваются особенности ассоциативных массивов структур данных или обработки поиска в массиве для более чем 40 языков компьютерного программирования .

Языковая поддержка

[ редактировать ]

Ниже приводится сравнение ассоциативных массивов (также «отображений», «хешей» и «словарей») в различных языках программирования.

AWK имеет встроенную поддержку ассоциативных массивов на уровне языка.

Например:

телефонная книга  [  "Салли Смарт"  ]   =   "555-9999"  телефонная книга  [  "Джон Доу"  ]   =   "555-1212"  телефонная книга  [  "Дж. Рэндом Хакер"  ]   =   "555-1337" 

Следующий код перебирает связанный массив и печатает его содержимое:

for   (  имя   в   телефонной книге  )   { 	 напечатать   имя  ,   ""  ,   телефонная книга  [  имя  ]  } 

Пользователь может искать элементы в ассоциативном массиве и удалять элементы из массива.

Ниже показано, как в стандартном AWK можно моделировать многомерные ассоциативные массивы с использованием конкатенации и встроенной переменной-разделителя строк SUBSEP:

{   # для каждой входной строки 	 multi  [  $  1   SUBSEP   $  2  ]  ++  ;  }  #  END   { 	 for   (  x   in   multi  )   { 		 Split  (  x  ,   arr  ,   SUBSEP  ); 		 напечатать   arr  [  1  ],   arr  [  2  ],   multi  [  x  ]; 	 }  } 

нет стандартной реализации ассоциативных массивов В C , но доступна сторонняя библиотека C Hash Table с лицензией BSD. [1]

Другая сторонняя библиотека, uthash, также создает ассоциативные массивы из структур C. Структура представляет значение, а одно из полей структуры служит ключом. [2]

Наконец, библиотека GLib также поддерживает ассоциативные массивы наряду со многими другими расширенными типами данных и является рекомендуемой реализацией проекта GNU. [3]

Подобно GLib , от Apple кросс-платформенная платформа Core Foundation предоставляет несколько основных типов данных. В частности, существуют CFDictionary и CFMutableDictionary с подсчетом ссылок.

C# использует классы коллекций, предоставляемые .NET Framework . Наиболее часто используемый тип ассоциативного массива: System.Collections.Generic.Dictionary<TKey, TValue>, который реализован как изменяемая хэш-таблица. Относительно новый System.Collections.Immutable пакет, доступный в .NET Framework версии 4.5 и выше, а также во всех версиях .NET Core , также включает в себя System.Collections.Immutable.Dictionary<TKey, TValue> тип, который реализован с помощью AVL-дерева . Методы, которые обычно изменяют объект на месте, вместо этого возвращают новый объект, который представляет состояние исходного объекта после мутации.

Создание

[ редактировать ]

Ниже демонстрируются три способа заполнения изменяемого словаря:

  • тот Add метод, который добавляет ключ и значение и выдает исключение, если ключ уже существует в словаре;
  • назначение индексатору, который перезаписывает любое существующее значение, если оно присутствует; и
  • присвоение резервному свойству индексатора, для которого индексатор является синтаксическим сахаром (не применимо к C#, см. примеры F# или VB.NET ).
вар   словарь   =   новый   словарь  <  строка  ,   строка  >  ();  словарь  .  Добавить  (  «Салли Смарт»  ,   «555-9999»  );  словарь  [  "Джон Доу"  ]   =   "555-1212"  ;  // Не разрешено в C#.  // словарь.Item("Дж.Рэндом Хакер") = "553-1337";  словарь  [  "Дж. Рэндом Хакер"  ]   =   "553-1337"  ; 

Словарь также можно инициализировать во время создания с помощью «инициализатора коллекции», который компилируется в повторяющиеся вызовы Add.

var   словарь   =   новый   словарь  <  строка  ,   строка  >   {      {   "Салли Смарт"  ,   "555-9999"   },      {   "Джон Доу"  ,   "555-1212"   },      {   "Дж. Рэндом Хакер"  ,   "553-1337"   }  }; 

Доступ по ключу

[ редактировать ]

Значения в основном извлекаются с помощью индексатора (который выдает исключение, если ключ не существует) и TryGetValue метод, который имеет выходной параметр для искомого значения и логическое возвращаемое значение, указывающее, был ли ключ найден.

var   sallyNumber   =   словарь  [  "Салли Смарт"  ]; 
var   sallyNumber   =   (  dictionary  .  TryGetValue  (  «Салли Смарт»  ,   )   результат var   :  ?   Результат   ;   «   н/д  » 

В этом примере sallyNumber значение теперь будет содержать строку "555-9999".

Перечисление

[ редактировать ]

Словарь можно рассматривать как последовательность ключей, последовательность значений или последовательность пар ключей и значений, представленных экземплярами KeyValuePair<TKey, TValue> типа, хотя гарантии порядка нет. Для отсортированного словаря программист может использовать SortedDictionary<TKey, TValue> или используйте .Sort LINQ Метод расширения при перечислении.

Ниже показано перечисление с использованием цикла foreach :

// проходим по коллекции и отображаем каждую запись.  foreach   (  KeyValuePair  <  строка  ,  строка  >   kvp   в   словаре  )  {      Console  .  WriteLine  (  "Номер телефона для {0}: {1}"  ,   kvp  .  Key  ,   kvp  .  Value  );  } 

В C++ есть форма ассоциативного массива, называемая std::map (см. Стандартная библиотека шаблонов#Контейнеры ). Карту телефонной книги можно создать с помощью следующего кода на C++:

#include   <map>  #include   <string>  #include   <utility>   int   main  ()   { 	 std  ::  map  <  std  ::  string  ,   std  ::  string  >   phone_book  ; 	 телефонная_книга  .  Insert  (  std  ::  make_pair  (  "Салли Смарт"  ,   "555-9999"  )); 	 телефонная_книга  .  Insert  (  std  ::  make_pair  (  "Джон Доу"  ,   "555-1212"  )); 	 телефонная_книга  .  Insert  (  std  ::  make_pair  (  "J.Random Hacker"  ,   "553-1337"  ));  } 

Или менее эффективно, поскольку это создает временные std::string ценности:

#include   <map>  #include   <string>   int   main  ()   { 	 std  ::  map  <  std  ::  string  ,   std  ::  string  >   phone_book  ; 	 phone_book  [  "Салли Смарт"  ]   =   "555-9999"  ; 	 phone_book  [  "Джон Доу"  ]   =   "555-1212"  ; 	 phone_book  [  "Дж. Рэндом Хакер"  ]   =   "553-1337"  ;  } 

Благодаря расширению списков инициализации в C++11 записи можно добавлять во время построения карты, как показано ниже:

#include   <map>  #include   <string>  int   main  ()   { 	 std  ::  map  <  std  ::  string  ,   std  ::  string  >   phone_book   { 		 {  "Салли Смарт"  ,   "555-9999"  }, 		 {  "Джон Доу"  ,   "555-1212"  }, 		 {  "Дж. Рэндом Хакер"  ,   "553-1337"  } 	 };  } 

Вы можете перебирать список с помощью следующего кода (C++03):

std  ::  map  <  std  ::  string  ,   std  ::  string  >::  итератор   curr  ,   end  ;  for  (  curr   =   phone_book.begin  !  (  ),   end   =   phone_book.end  curr  curr  ();    =   ++   )  end;    std  ::  cout 	 <<  curr  -   >    первый  <<  "   =   "   <<   curr  ->  второй   <<   станд  ::  конец  ; 

Та же задача в C++11:

for  (  const   auto  &   curr   :   phone_book  )          std  ::  cout   <<    curr  .  первый   <<   " = "   <<   текущий  .  второй   <<   std  ::  endl  ; 

Использование структурированной привязки, доступной в C++17 :

for   (  const   auto  &   [  имя  ,   номер  ]   :   phone_book  )   {      std  ::  cout   <<   name   <<   " = "   <<   Number   <<   std  ::  endl  ;  } 

В С++ std::map Класс является шаблонным , что позволяет типам данных ключей и значений быть разными для разных map экземпляры. Для данного экземпляра map class, ключи должны быть одного и того же базового типа. То же самое должно быть верно для всех ценностей. Хотя std::map обычно реализуется с использованием самобалансирующегося двоичного дерева поиска , C++11 определяет вторую карту, называемую std::unordered_map, который имеет алгоритмические характеристики хеш-таблицы. распространенное расширение стандартной библиотеки шаблонов (STL), обычно называемое Это также hash_map, доступный в таких реализациях, как SGI и STLPort.

Инициализация пустого словаря и добавление элементов в Cobra :

 dic   as   Словарь  <  of   String  ,   String  >   =   Словарь  <  of   String  ,   String  >  ()   dic  .  добавить  (  «Салли Смарт»  ,   «555-9999»  )   dic  .  добавить  (  'Джон Доу'  ,   '555-1212'  )   dic  .  add  (  'J. Random Hacker'  ,   '553-1337'  )    Assert   dic  [  'Sally Smart'  ]   ==   '555-9999' 

В качестве альтернативы словарь может быть инициализирован всеми элементами во время создания:

 dic   =   {             'Салли Смарт'  :  '555-9999'  ,             'Джон Доу'  :  '555-1212'  ,             'Дж. Случайный хакер'  :  '553-1337'         } 

Словарь можно перечислить с помощью цикла for, но гарантированного порядка не существует:

 для   ключа  ,   val   в   dic       print   «Номер телефона [key] — [val]» 

Язык разметки ColdFusion

[ редактировать ]

Структура в языке разметки ColdFusion (CFML) эквивалентна ассоциативному массиву:

DynamicKeyName   =   "Джон Доу"  ;  phoneBook   =   { 	 "Салли Смарт"   =   "555-9999"  , 	 "  #dynamicKeyName#  "   =   "555-4321"  , 	 "Дж. Рэндом Хакер"   =   "555-1337"  , 		 UnknownComic   =   "???"  };  writeOutput  (  phoneBook.UnknownComic  );   // ???  writeDump  (  телефонная книга  );   // вся структура 

D предлагает прямую поддержку ассоциативных массивов на основном языке; такие массивы реализованы как цепочка хеш-таблиц с двоичными деревьями. [4] Эквивалентным примером может быть:

int   main  ()   { 	 строка  [   строка   ]   телефонная_книга  ; 	 phone_book  [  "Салли Смарт"  ]   =   "555-9999"  ; 	 phone_book  [  "Джон Доу"  ]   =   "555-1212"  ; 	 phone_book  [  "Дж. Рэндом Хакер"  ]   =   "553-1337"  ; 	 вернуть   0  ;  } 

Ключи и значения могут быть любого типа, но все ключи в ассоциативном массиве должны быть одного типа, то же самое касается и зависимых значений.

Перебор всех свойств и связанных значений и их печать можно закодировать следующим образом:

foreach   (  key  ,   value  ;   phone_book  )   {          writeln  (  "Номер для "   ~   key   ~   ":"   ~   value   );  } 

Свойство можно удалить следующим образом:

телефонная_книга  .  удалить  (  «Салли Смарт»  ); 

Delphi поддерживает несколько стандартных контейнеров, включая TDictionary<T>:

использует    SysUtils  ,    Generics  .  Коллекции  ;  var    PhoneBook  :   TDictionary  <  строка  ,   строка  >;    Запись  :   TPair  <  строка  ,   строка  >;  начать    Телефонную книгу   :=   TDictionary  <  строка  ,   строка  >.  Создавать  ;    Телефонная книга  .  Добавить  (  'Салли Смарт'  ,   '555-9999'  )  ;    Телефонная книга  .  Добавить  (  'Джон Доу'  ,   '555-1212'  )  ;    Телефонная книга  .  Добавить  (  'Дж. Рэндом Хакер'  ,   '553-1337'  )  ;    для   записи   в   телефонной книге   сделайте      Writeln  (  Format  (  «Номер для %s: %s»  ,  [  Entry  .  Key  ,   Entry  .  Value  ]))  ;  конец  . 

Версии Delphi до 2009 года не поддерживают напрямую ассоциативные массивы. Такие массивы можно моделировать с помощью класса TStrings:

процедура   TForm1  .  Button1Click  (  Отправитель  :   TObject  )  ;  вар    DataField  :   TStrings  ;    я  :   целое число  ;  начать    DataField   :=   TStringList  .  Создавать  ;    Поле данных  .  Значения  [  'Салли Смарт'  ]   :=   '555-9999'  ;    Поле данных  .  Значения  [  'Джон Доу'  ]   :=   '555-1212'  ;    Поле данных  .  Ценности  [  'Дж. Случайный хакер'  ]   :=   '553-1337'  ;    // получаем доступ к записи и отображаем ее в окне сообщения    ShowMessage  (  DataField  .  Values  ​​[  'Sally Smart'  ])  ;    // циклически перебираем ассоциативный массив    for   i   :=   0   в   DataField  .  Count   -   1   do    Begin      ShowMessage  (  'Number for'   +   DataField  .  Names  [  i  ]   +   ':'   +   DataField  .  ValueFromIndex  [  i  ])  ;    конец  ;    Поле данных  .  Бесплатно  ;  конец  ; 

Erlang предлагает множество способов представления отображений; три наиболее распространенных в стандартной библиотеке — это списки ключей, словари и карты.

Списки клавиш

[ редактировать ]

Списки ключей — это списки кортежей , где первый элемент каждого кортежа — это ключ, а второй — значение. Функции для работы со списками клавиш представлены в разделе lists модуль.

PhoneBook   =   [{  "Салли Смит"  ,   "555-9999"  },               {  "Джон Доу"  ,   "555-1212"  },               {  "Дж. Рэндом Хакер"  ,   "553-1337"  }]. 

Доступ к элементу списка ключей можно осуществить с помощью lists:keyfind/3 функция:

{_,   Phone  }   =   lists  :  keyfind  (  «Sally Smith»  ,   1  ,   PhoneBook  ),  io  :  format  (  «Номер телефона:  ~s~n  »  ,   [  Phone  ]). 

Словари реализованы в dict модуль стандартной библиотеки. Новый словарь создается с помощью dict:new/0 функция и новые пары ключ/значение сохраняются с использованием dict:store/3 функция:

PhoneBook1   =   dict  :  new  (),  PhoneBook2   =   dict  :  store  (  «Салли Смит»  ,   «555-9999»  ,   Dict1  ),  PhoneBook3   =   dict  :  store  (  «Джон Доу»  ,   «555-1212»  ,   Dict2  ),  PhoneBook   =   dict  :  store  (  «J. Random Hacker»  ,   «553-1337»  ,   Dict3  ). 

Такая последовательная инициализация была бы более идиоматично представлена ​​в Erlang соответствующей функцией:

PhoneBook   =   dict  :  from_list  ([{  "Салли Смит"  ,   "555-9999"  },                              {  "Джон Доу"  ,   "555-1212"  },                              {  "Дж. Рэндом Хакер"  ,   "553-1337"  }]). 

Доступ к словарю можно получить с помощью dict:find/2 функция:

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

В обоих случаях в качестве ключа можно использовать любой термин Эрланга. Вариации включают в себя orddict модуль, реализующий упорядоченные словари, и gb_trees, реализуя общие сбалансированные деревья.

Карты были представлены в OTP 17.0, [5] и объединить сильные стороны списков клавиш и словарей. Карта определяется с использованием синтаксиса #{ K1 => V1, ... Kn => Vn }:

PhoneBook   =   #{  "Салли Смит"   =>   "555-9999"  ,                "Джон Доу"   =>   "555-1212"  ,                "Дж. Рэндом Хакер"   =>   "553-1337"  }. 

Основные функции для взаимодействия с картами доступны из maps модуль. Например, maps:find/2 функция возвращает значение, связанное с ключом:

{  ок  ,   Телефон  }   =   карты  :  найти  (  «Салли Смит»  ,   Телефонная книга  ),  io  :  формат  (  «Телефон:  ~s~n  »  ,   [  Телефон  ]). 

В отличие от словарей, карты могут быть сопоставлены с образцом:

#{  "Салли Смит"  ,   Phone  }   =   PhoneBook  ,  io  :  format  (  "Phone:  ~s~n  "  ,   [  Phone  ]). 

Erlang также предоставляет синтаксический сахар для функциональных обновлений — создание новой карты на основе существующей, но с измененными значениями или дополнительными ключами:

PhoneBook2   =   PhoneBook  #{      % оператор `:=` обновляет значение, связанное с существующим ключом      "J. Random Hacker"   :  =   "355-7331"  ,      % оператор `=>` добавляет новую пару ключ-значение, потенциально замена существующего      "Страна чудес Алисы"   =>   "555-1865"  } 

Карта<'Ключ,'Значение>

[ редактировать ]

Во время выполнения F# предоставляет Collections.Map<'Key,'Value> type, который представляет собой неизменяемое дерево AVL .

Создание
[ редактировать ]

В следующем примере вызывается Map конструктор, который работает со списком (последовательностью элементов, разделенных точкой с запятой, заключенной в квадратные скобки) кортежей (которые в F# представляют собой последовательности элементов, разделенных запятыми).

let   Numbers   =      [          "Салли Смарт"  ,   "555-9999"  ;           «Джон Доу»  ,   «555-1212»  ;          "Дж. Рэндом Хакер"  ,   "555-1337"      ]   |>   Карта 
Доступ по ключу
[ редактировать ]

Значения можно просмотреть с помощью одного из Map члены, такие как его индексатор или Item свойство (которое генерирует исключение , если ключ не существует) или TryFind функция, которая возвращает тип опции со значением Some <result>, для успешного поиска, или None, за неудачный. Затем можно использовать сопоставление с образцом для извлечения необработанного значения из результата или установить значение по умолчанию.

let   sallyNumber   =   Numbers  .[  "Sally Smart"  ]  // или  let   sallyNumber   =   Numbers  .  Предмет  (  «Салли Смарт»  ) 
пусть   sallyNumber   =      совпадений   номера  .  Попробуйте найти  (  «Салли Смарт»  )   с помощью      |   Некоторые  (  число  )   ->   число      |   Нет           ->   «н/д» 

В обоих приведенных выше примерах sallyNumber значение будет содержать строку "555-9999".

Словарь<'TKey,'TValue>

[ редактировать ]

Поскольку F# — это язык .NET, он также имеет доступ к функциям .NET Framework , включая System.Collections.Generic.Dictionary<'TKey,'TValue> type (который реализован в виде хеш-таблицы ), который является основным типом ассоциативного массива, используемым в C# и Visual Basic. Этот тип может быть предпочтителен при написании кода, предназначенного для работы с другими языками в .NET Framework, или когда характеристики производительности хеш-таблицы предпочтительнее характеристик производительности дерева AVL.

Создание
[ редактировать ]

The dict Функция предоставляет средства удобного создания словаря .NET, который не предназначен для изменения; он принимает последовательность кортежей и возвращает неизменяемый объект, реализующий IDictionary<'TKey,'TValue>.

let   Numbers   =      [          "Салли Смарт"  ,   "555-9999"  ;           «Джон Доу»  ,   «555-1212»  ;          "Дж. Рэндом Хакер"  ,   "555-1337"      ]   |>   dict 

Когда необходим изменяемый словарь, конструктор System.Collections.Generic.Dictionary<'TKey,'TValue> можно позвонить напрямую. см. в примере C# на этой странице Дополнительную информацию .

пусть   числа   =   Система  .  Коллекции  .  Общий  .  Словарь  <  строка  ,   строка  >  ()  чисел  .  Добавьте  (  «Салли Смарт»  ,   «555-9999»  )  номера  . [  «Джон Доу»  ]   <-   «555-1212»  номера  .  Предмет  (  «Дж. Рэндом Хакер»  )   <-    «555-1337» 
Доступ по ключу
[ редактировать ]

IDictionary экземпляры имеют индексатор, который используется так же, как и Map, хотя это эквивалентно TryFind является TryGetValue, который имеет выходной параметр для искомого значения и возвращаемое логическое значение, указывающее, был ли ключ найден.

let   sallyNumber   =      let   mutable   result   =   ""      if   Numbers  .  TryGetValue  (  "Sally Smart"  и   затем  result  ),   результат   else   "   n/a" 

F# также позволяет вызывать функцию так, как если бы она не имела выходного параметра и вместо этого возвращала кортеж, содержащий ее обычное возвращаемое значение и значение, присвоенное выходному параметру:

пусть   sallyNumber   =      совпадений   номера  .  TryGetValue  (  «Салли Смарт»  )   с      |   правда  ,   число   ->   число      |   _       ->   "н/д" 

Перечисление

[ редактировать ]

Словарь или карту можно перечислить с помощью Seq.map.

// проходим по коллекции и отображаем каждую запись.  числа   |>   След  .  карта   (  fun   kvp   ->   printfn   «Номер телефона для %O равен %O»   kvp  .  Key   kvp  .  Value  ) 

Visual FoxPro реализует сопоставление с помощью класса коллекции.

отображение  =  NEWOBJECT  (  «Коллекция»  ) сопоставление  .Add  (  «Нарциссы»  ,  «цветок2»  )  && Add(object, key) – ключ должен быть символьным  индексом  = сопоставление  .GetKey  (  «цветок2»  )  && возвращает значение индекса 1  объект  = сопоставление(  «цветок2»  )  && возвращает «Нарциссы» (получить по ключу)  object  = Mapping(1)  && возвращает «Нарциссы» (получить по индексу) 

GetKey возвращает 0, если ключ не найден.

Go имеет встроенную поддержку ассоциативных массивов на уровне языка, называемых «картами». Тип ключа карты может быть только логическим, числовым, строковым, массивом, структурой, указателем, интерфейсом или типом канала.

Тип карты пишется: map[keytype]valuetype

Добавляем элементы по одному:

phone_book   :=   make  (  map  [  string  ]   string  )   // создаем пустую карту  phone_book  [  "Салли Смарт"  ]   =   "555-9999"  phone_book  [  "Джон Доу"  ]   =   "555-1212"  phone_book  [  "Дж. Рэндом Хакер" "  ]   =   "553-1337" 

Литерал карты:

phone_book   :=   карта  [  строка  ]   строка   { 	 "Салли Смарт"  :   "555-9999"  , 	 "Джон Доу"  :   "555-1212"  , 	 "Дж. Рэндом Хакер"  :   "553-1337"  ,  } 

Итерация по карте:

// как для ключей, так и  для   значений key  ,   value   :=   range   phone_book   { 	 fmt  .  Printf  (  "Номер для %s: %s\n"  ,   key  ,   value  )  }  // только ключи  для   key   :=   range   phone_book   { 	 fmt  .  Printf  (  "Имя: %s\n"  ,   ключ  )  } 

Язык программирования Haskell предоставляет только один вид ассоциативного контейнера — список пар:

m   =   [(  "Салли Смарт"  ,   "555-9999"  ),   (  "Джон Доу"  ,   "555-1212"  ),   (  "Дж. Рэндом Хакер"  ,   "553-1337"  )]  main   =   print   (  поиск   " Джон Доу»   м  ) 

выход:

Просто "555-1212" 

Обратите внимание, что функция поиска возвращает значение «Может быть», которое равно «Ничего», если не найдено, или «Просто «результат » », если найдено.

Компилятор Glasgow Haskell (GHC), наиболее часто используемая реализация Haskell, предоставляет еще два типа ассоциативных контейнеров. Другие реализации также могут обеспечить это.

Один из них — полиморфные функциональные карты (представленные в виде неизменяемых сбалансированных двоичных деревьев):

импортируйте   квалифицированный   Data.Map   как   M  m   =   M  .  вставка   «Салли Смарт»   «555-9999»   М  .  пустой  m'   =   M  .  вставьте   «Джон Доу»   «555-1212»   м  м''   =   М  .  вставить   "J. Random Hacker"   "553-1337"   m'  main   =   print   (  M  .  поиск   "John Doe"   m''   ::   Maybe   String  ) 

выход:

Просто "555-1212" 

Специализированная версия для целочисленных ключей также существует как Data.IntMap.

Наконец, полиморфная хеш-таблица:

импортируйте   квалифицированный   Data.HashTable   как   H  main   =   do   m   <-   H  .  новый   (  ==  )   Ч  .  хеш-строка            H  .  вставка   м   «Салли Смарт»   «555-9999»            H  .  вставка   м   «Джон Доу»   «555-1212»            H  .  вставьте   m   "J. Random Hacker"   "553-1337"            foo   <-   H  .  поиск   m   "Джон Доу"            print   foo 

выход:

Просто "555-1212" 

Списки пар и функциональные карты предоставляют чисто функциональный интерфейс, который в Haskell более идиоматичен. Напротив, хэш-таблицы предоставляют императивный интерфейс в монаде ввода-вывода .

В Java ассоциативные массивы реализованы как «карты», которые являются частью структуры коллекций Java . Начиная с J2SE 5.0 и появления дженериков в Java, для коллекций может быть указан тип; например, ассоциативный массив, который сопоставляет строки со строками, может быть указан следующим образом:

Карта  <  String  ,   String  >   телефонная книга   =   новый   HashMap  <  String  ,   String  >  ();  телефонная книга  .  поставьте  (  "Салли Смарт"  ,   "555-9999"  );  телефонная книга  .  put  (  "Джон Доу"  ,   "555-1212"  );  телефонная книга  .  put  (  "J.Random Hacker"  ,   "555-1337"  ); 

The get метод используется для доступа к ключу; например, значение выражения phoneBook.get("Sally Smart") является "555-9999". Этот код использует хеш-карту для хранения ассоциативного массива, вызывая конструктор HashMap сорт. Однако, поскольку в коде используются только методы, общие для интерфейса Mapсамобалансирующееся двоичное дерево можно использовать, вызвав конструктор TreeMap класс (который реализует подинтерфейс SortedMap), не меняя определения phoneBook переменную или остальную часть кода или использование других базовых структур данных, которые реализуют Map интерфейс.

Хэш-функция в Java, используемая HashMap и HashSet, предоставляется Object.hashCode() метод. Поскольку каждый класс в Java наследуется от Object, каждый объект имеет хеш-функцию. Класс может переопределить реализацию по умолчанию. hashCode() чтобы предоставить пользовательскую хеш-функцию, более соответствующую свойствам объекта.

The Object класс также содержит equals(Object) метод, который проверяет объект на равенство с другим объектом. Хешированные структуры данных в Java полагаются на объекты, поддерживающие следующий контракт между своими hashCode() и equals() методы:

Для двух a и b объектов

а  .  равно  (  б  )   ==   б  .  равно  (  a  ),  если   a  .  равно  (  b  ),   тогда   a  .  хеш-код  ()   ==   b  .  хэш-код  () 

Чтобы поддерживать этот контракт, класс, который переопределяет equals() также необходимо переопределить hashCode(), и наоборот, так что hashCode() основан на тех же свойствах (или подмножестве свойств), что и equals().

Еще одним соглашением, которое хешированная структура данных имеет с объектом, является то, что результаты hashCode() и equals() методы не изменятся после вставки объекта на карту. По этой причине обычно рекомендуется основывать хэш-функцию на неизменяемых свойствах объекта.

Аналогично, TreeMap и другие отсортированные структуры данных требуют, чтобы порядок был определен для типа данных. Либо тип данных уже должен определить свой собственный порядок, реализовав Comparable интерфейс; или обычай Comparator должны быть предоставлены во время создания карты. Как и в случае с HashMap, описанным выше, относительный порядок ключей в TreeMap не должен меняться после их вставки в карту.

JavaScript (и его стандартизированная версия ECMAScript ) — это язык , основанный на прототипах объектно-ориентированный .

Карта и WeakMap

[ редактировать ]

Современный JavaScript обрабатывает ассоциативные массивы, используя метод Map и WeakMap занятия. По умолчанию карта не содержит ключей; он содержит только то, что в него явно вложено. Ключи и значения могут быть любого типа (включая функции, объекты или любые примитивы).

Создание
[ редактировать ]

Карта может быть инициализирована всеми элементами во время построения:

const   phoneBook   =   новая   карта  ([      [  "Салли Смарт"  ,   "555-9999"  ],      [  "Джон Доу"  ,   "555-1212"  ],      [  "Дж. Рэндом Хакер"  ,   "553-1337"  ],  ]) ; 

Альтернативно вы можете инициализировать пустую карту, а затем добавлять элементы:

const   телефонная книга   =   новая   карта  ();  телефонная книга  .  набор  (  «Салли Смарт»  ,   «555-9999»  );  телефонная книга  .  набор  (  «Джон Доу»  ,   «555-1212»  );  телефонная книга  .  набор  (  «Дж. Рэндом Хакер»  ,   «553-1337»  ); 
Доступ по ключу
[ редактировать ]

Доступ к элементу карты можно осуществить с помощью get метод:

const   sallyNumber   =   телефонная книга  .  получить  (  «Салли Смарт»  ); 

В этом примере значение sallyNumber теперь будет содержать строку «555-9999».

Перечисление
[ редактировать ]

Ключи на карте упорядочены. Таким образом, при проходе по нему объект карты возвращает ключи в порядке вставки. Ниже показано перечисление с использованием цикла for:

// проходим по коллекции и отображаем каждую запись.  for   (  const   [  имя  ,   номер  ]   телефонной   книги  )   {      console  .  log  (  `Номер телефона для  ${  name  }  равен  ${  number  }  `  );  } 

Ключ можно удалить следующим образом:

телефонная книга  .  удалить  (  «Салли Смарт»  ); 

Объект похож на карту: оба позволяют устанавливать ключи для значений, извлекать эти значения, удалять ключи и определять, хранится ли значение в ключе. По этой причине (а также из-за отсутствия встроенных альтернатив) объекты исторически использовались в качестве карт.

Однако есть важные различия, которые делают карту предпочтительнее в определенных случаях. В JavaScript объект представляет собой сопоставление имен свойств со значениями, то есть ассоциативный массив с одной оговоркой: ключи объекта должны быть либо строкой, либо символом (допускаются собственные объекты и примитивы, неявно преобразованные в строковые ключи). . Объекты также включают одну особенность, не связанную с ассоциативными массивами: у объекта есть прототип, поэтому он содержит ключи по умолчанию, которые могут конфликтовать с ключами, определяемыми пользователем. Таким образом, поиск свойства приведет к поиску определения прототипа, если объект не определяет свойство.

Литерал объекта записывается как { property1: value1, property2: value2, ... }. Например:

const   myObject   =   {      "Салли Смарт"  :   "555-9999"  ,      "Джон Доу"  :   "555-1212"  ,      "Дж. Рэндом Хакер"  :   "553-1337"  ,  }; 

Чтобы запретить поиску использовать свойства прототипа, вы можете использовать Object.setPrototypeOf функция:

Объект  .  setPrototypeOf  (  myObject  ,   null  ); 

Начиная с ECMAScript 5 (ES5), прототип также можно обойти, используя Object.create(null):

константный   мойОбъект   =   Объект  .  создать  (  ноль  );  Объект  .  Assign  (  myObject  ,   {      "Салли Смарт"  :   "555-9999"  ,      "Джон Доу"  :   "555-1212"  ,      "Дж. Рэндом Хакер"  :   "553-1337"  ,  }); 

Если имя свойства является допустимым идентификатором, кавычки можно опустить, например:

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

Поиск записывается с использованием нотации доступа к свойствам: либо квадратных скобок, которые всегда работают, либо точечной нотации, которая работает только для ключей-идентификаторов:

myObject  [  "Джон Доу"  ]  myOtherObject  .  фу 

Вы также можете перебирать все перечисляемые свойства и связанные значения следующим образом (цикл for-in):

for   (  const   свойство   в   myObject  )   {      const   value   =   myObject  [  property  ];      консоль  .  log  (  `myObject[  ${  свойство  }  ] =  ${  значение  }  `  );  } 

Или (цикл for):

for   (  const   [  свойство  ,   значение  ]   Object   .  .  elements  (  myObject  )   {      console  )  log  (  `  ${  свойство  }  =  ${  значение  }  `  );  } 

Свойство можно удалить следующим образом:

удалить   myObject  [  "Салли Смарт"  ]; 

Как упоминалось ранее, свойства — это строки и символы. Поскольку каждый собственный объект и примитив можно неявно преобразовать в строку, вы можете сделать:

myObject  [  1  ]                                          // ключ «1»; обратите внимание, что myObject[1] == myObject["1"]  myObject  [[  "a"  ,   "b"  ]]                                 // ключ — "a,b"  myObject  [{   toString  ()   {   return   "hello world"  ;   }   }]   // ключ — «привет, мир» 

В современном JavaScript считается дурным тоном использовать тип Array в качестве ассоциативного массива. Консенсус заключается в том, что тип объекта и Map/ WeakMap занятия лучше всего подходят для этой цели. Причина этого заключается в том, что если Array расширяется с помощью прототипа, а Object остается в первозданном виде, циклы for и for-in будут работать должным образом на ассоциативных «массивах». Эта проблема выдвинулась на передний план из-за популярности фреймворков JavaScript, которые интенсивно и иногда неизбирательно используют прототипы для расширения встроенных типов JavaScript.

см . День осведомленности о массивах и прототипах объектов JavaScript Для получения дополнительной информации по этой проблеме .

В Julia следующие операции управляют ассоциативными массивами.

Объявить словарь:

 телефонная книга   =   Dict  (   «Салли Смарт»   =>   «555-9999»  ,   «Джон Доу»   =>   «555-1212»  ,   «Дж. Рэндом Хакер»   =>   «555-1337»   ) 

Элемент доступа:

телефонная книга["Салли Смарт"] 

Добавить элемент:

телефонная книга["Новый контакт"] = "555-2222" 

Удалить элемент:

удалить!(телефонная книга, "Салли Смарт") 

Получите ключи и значения в виде итераций :

ключи (телефонная книга)ценности (телефонная книга) 

KornShell 93 и совместимые оболочки

[ редактировать ]

В KornShell 93 и совместимых оболочках (ksh93, bash4...) с ассоциативными массивами можно использовать следующие операции.

Определение:

 верстка   -   Телефонная книга  ;   # ksh93   объявить   -   Телефонную книгу  ;   bash4   # телефонная книга  =([  "Салли Смарт"  ]=  "555-9999"   [  "Джон Доу"  ]=  "555-1212"   [  "[[Дж. Рэндом Хакер]]"  ]=  "555-1337"  )  ; 

Разыменование:

 ${  телефонная книга  [  "Джон Доу"  ]  }  ; 

Первоначально Lisp был задуман как язык «обработки списков», и одним из его наиболее важных типов данных является связанный список, который можно рассматривать как список ассоциаций («alist»).

'  ((  "Салли Смарт"   .   "555-9999"  )    (  "Джон Доу"   .   ​​"555-1212"  )    (  "Дж. Рэндом Хакер"   .   "553-1337"  )) 

Синтаксис (x . y) используется для обозначения consпара изд . Ключи и значения не обязательно должны быть одного типа в списке. Lisp и Scheme предоставляют такие операторы, как assoc манипулировать списками способами, аналогичными ассоциативным массивам.

существует набор операций, специфичных для обработки списков ассоциаций Для Common Lisp , каждая из которых работает неразрушающе.

Чтобы добавить запись, acons используется функция, создающая и возвращающая новый список ассоциаций. Список ассоциаций в Common Lisp имитирует стек, то есть придерживается принципа «последним пришел — первым вышел» (LIFO) и, следовательно, добавляется в начало списка.

(  let   ((  телефонная книга   NIL  ))    (  setf   телефонная книга   (  acons   "Салли Смарт"        "555-9999"   телефонная книга  ))    (  setf   телефонная книга   (  acons   "Джон Доу"           "555-1212"   телефонная книга)  ))    (  setf   телефонная книга   (  acons   "J. Random Hacker"   "555-1337"   телефонная книга  ))) 

Эту функцию можно рассматривать как приспособление для cons операции. [6]

;; Эффект  ;; (минусы (минусы КЛЮЧЕВОЕ ЗНАЧЕНИЕ) ALIST)  ;; эквивалентно  ;; (acons СПИСОК ЗНАЧЕНИЙ КЛЮЧЕЙ)  (  let   ((  телефонная книга   '  ((  "Салли Смарт"   .   "555-9999"  )   (  "Джон Доу"   .   "555-1212"  ))))    (  cons   (  cons   "Дж. Рэндом Хакер"   "555-1337"  )   телефонная книга  )) 

Конечно, разрушительное push Операция также позволяет вставлять записи в список ассоциаций, причем запись должна представлять собой минус «ключ-значение», чтобы сохранить достоверность сопоставления.

(  нажать   (  минусы   "Пустышка"   "123-4567"  )   телефонная книга  ) 

Поиск записи по ее ключу осуществляется через assoc, который можно настроить для предиката и направления проверки, особенно для поиска в списке ассоциаций от конца к началу. Результат, если он положительный, возвращает все минусы записи, а не только ее значение. Невозможность получить соответствующий ключ приводит к возврату NIL ценить.

(  :   "Джона Доу"   телефонная книга   test   #'  string=  ) 

Два обобщения assoc существовать: assoc-if ожидает функцию предиката, которая проверяет ключ каждой записи, возвращая первую запись, для которой предикат выдает неверный результат. NIL значение при вызове. assoc-if-not инвертирует логику, принимая те же аргументы, но возвращая первую запись, генерирующую NIL.

;; Найдите первую запись, ключ которой равен «Джон Доу».  (  assoc-if    #'  (  лямбда   (  ключ  )        (  строка =   ключ   "Джон Доу"  ))    телефонная книга  )  ;; Находит первую запись, ключ которой не является ни «Салли Смарт», ни «Джон Доу»  (  assoc-if-not    #'  (  лямбда   (  ключ  )        (  участника   ключ   '  (  «Салли Смарт»   «Джон Доу»  )   :test   #'  string=  ))    телефонная книга  ) 

Обратный процесс, обнаружение записи по ее значению, использует rassoc.

;; Найдите первую запись со значением «555-9999».  ;; Мы проверяем значения входной строки с помощью предиката «string=".  (  rassoc   "555-9999"   телефонная книга   :test   #'  string=  ) 

Соответствующие обобщения rassoc-if и rassoc-if-not существовать.

;; Находит первую запись со значением «555-9999».  (  rassoc-if    #'  (  лямбда   (  значение  )        (  строка =   значение   "555-9999"  ))    телефонная книга  )  ;; Находит первую запись, значение которой отличается от «555-9999».  (  rassoc-if-not    #'  (  лямбда   (  значение  )        (  строка =   значение   "555-9999"  ))    телефонная книга  ) 

Все предыдущие функции поиска записей могут быть заменены общими вариантами, ориентированными на списки, такими как find, find-if, find-if-not, а также соответствующие функции, такие как position и его производные.

;; Найдите запись с ключом «Джон Доу» и значением «555-1212».  (  найти   (  cons   "Джон Доу"   "555-1212"  )   телефонная книга   : тест   #'  равен  ) 

Удаление, не имеющее конкретного аналога, осуществляется на основе списков объектов, в том числе деструктивных.

;; Создайте и верните список без каких-либо записей, ключ которого равен «Джон Доу».  (  remove-if    #'  (  лямбда   (  запись  )        (  строка=   (  о машине   запись  )   "Джон Доу"  ))    телефонная книга  ) 

Итерация выполняется с помощью любой функции, которая ожидает список.

;; Итерация через «карту».  (  map   NIL    #'  (  лямбда   (  запись  )        (  деструктуризация-привязка   (  ключ   .   значение  )   запись          (  формат   T   "~&~s => ~s"   ключа   значение  )))    телефонная книга  )  ;; Итерация через «dolist».  (  dolist   (  запись   телефонной книге  )    (  запись деструктуризации-привязки   (  ключ   .   значение  )   формат      (  T   в   "~&~s => ~s"   ключа   значение  ))) 

Поскольку это структурированные списки, операции обработки и преобразования могут применяться без ограничений.

;; Верните вектор значений «телефонной книги».  (  карта   'вектор   #'  cdr   телефонная книга  )  ;; Деструктивно изменить «телефонную книгу» с помощью «map-into».  (  сопоставление-в   телефонной книге    #'  (  лямбда   (  запись  )        (  деструктуризация-привязка   (  ключ   .   значение  )   запись          (  cons   (  обратный   ключ  )   (  обратное   значение  ))))    телефонная книга  ) 

Из-за своей линейной природы списки используются для относительно небольших наборов данных. Common Lisp также поддерживает тип данных хеш-таблицы , а для Scheme они реализованы в SRFI 69. Хеш-таблицы требуют больше накладных расходов, чем списки, но обеспечивают гораздо более быстрый доступ при наличии большого количества элементов. Еще одной особенностью является тот факт, что хеш-таблицы Common Lisp, в отличие от списков ассоциаций, не поддерживают порядок вставки записей.

Хэш-таблицы Common Lisp создаются с помощью make-hash-table функция, аргументы которой, помимо других конфигураций, включают в себя предикат для проверки ключа входа. Допуская произвольные объекты, даже неоднородность в пределах одного экземпляра хэш-таблицы, спецификация этого ключа :test функция ограничена различимыми сущностями: стандарт Common Lisp требует поддержки только eq, eql, equal, и equalp, но при этом обозначая дополнительные или пользовательские операции как разрешенные для конкретных реализаций.

(  let   ((  телефонная книга   (  make-hash-table   :test   #'  равно  )))    (  setf   (  gethash   "Салли Смарт"        телефонная книга  )   "555-9999"  )    (  setf   (  gethash   "Джон Доу"           телефонная книга  )   "555-1212"  )    (  setf   (  gethash   "J. Random Hacker"   телефонная книга  )   "553-1337"  )) 

The gethash функция позволяет получить значение, связанное с ключом.

(  gethash   "Джон Доу"   телефонная книга  ) 

Кроме того, можно указать значение по умолчанию для случая отсутствия ключа.

(  gethash   «Инкогнито» «   телефонной книги   нет такого ключа»  ) 

Вызов gethash фактически возвращает два значения: значение или замещающее значение ключа и логический индикатор, возвращая T если хеш-таблица содержит ключ и NIL сигнализировать о его отсутствии.

(  привязка нескольких значений   (  значение   содержит ключ  )   (  gethash   "Sally Smart"   телефонная книга  )    (  if   contains-key      (  формат   T   "~&Связанное значение:   значение  ~s" )      (  формат   T   "~&Ключ может не найти."  ))) 

Использовать remhash для удаления записи, связанной с ключом.

(  ремхэш   "J. Random Hacker"   телефонной книги  ) 

clrhash полностью очищает хеш-таблицу.

(  clrhash   телефонная книга  ) 

Посвященный maphash функция специализируется на итерации хэш-таблиц.

(  maphash    #'  (  лямбда   (  ключа   значение  )        (  формат   T   "~&~s => ~s"   ключа   значение  ))    телефонная книга  ) 

Альтернативно, loop Конструкция предусматривает итерации через ключи, значения или их сочетание.

;; Переберите ключи и значения хеш-таблицы.  (  цикл    для     ключа   представляет собой   хеш   -ключи   телефонной   книги    с использованием   (  хэш-значения   значение  )    do      (  формат   T   "~&~s => ~s"   ключа   значение  ) )  ;; Переберите значения хеш-таблицы.  (  цикл    для   значения   , представляющего собой   хэш   -значения   телефонной   книги    do    (  печати   значение  )) 

Дополнительная опция вызывает with-hash-table-iterator, макрос, создающий итератор, обработка которого должна управляться вызывающей стороной.

(  with-hash-table-iterator   (  -генератор записей   телефонная книга  )    (  цикл   do      (  привязка нескольких значений   (  имеет запись   ключа   значение  )   (  генератор-запись  )        (  if   has-entry          (  формат   T   "~&~s => ~s"   ключевое   значение  )          (  завершение цикла  ))))) 

В Lisp легко создавать составные абстрактные типы данных, используя структуры или функции объектно-ориентированного программирования в сочетании со списками, массивами и хеш-таблицами.

LPC реализует ассоциативные массивы как фундаментальный тип, известный как «карта» или «отображение», в зависимости от драйвера. Ключи и значения могут быть любого типа. Литерал отображения записывается как ([ key_1 : value_1, key_2 : value_2 ]). Процедурный код выглядит так:

отображение   телефонной книги   =   ([]);  phone_book  [  "Салли Смарт"  ]   =   "555-9999"  ;  phone_book  [  "Джон Доу"  ]   =   "555-1212"  ;  phone_book  [  "Дж. Рэндом Хакер"  ]   =   "555-1337"  ; 

Доступ к сопоставлениям для чтения осуществляется с помощью оператора индексации так же, как и для записи, как показано выше. Таким образом, phone_book["Салли Смарт"] вернет строку "555-9999", а phone_book["Джон Смит"] вернет 0. Проверка присутствия выполняется с помощью функцииmember(), например if(member(phone_book, "John Smith")) write("John Smith is listed.\n");

Удаление выполняется с помощью функции m_delete() или map_delete(), в зависимости от драйвера: m_delete(phone_book, "Sally Smart");

Драйверы LPC семейства Amylaar реализуют многозначные сопоставления с использованием вторичного числового индекса (другие драйверы семейства MudOS не поддерживают многозначные сопоставления). Пример синтаксиса:

отображение   телефонной_книги   =   ([  :  2  ]);  phone_book  [  "Салли Смарт"  ,   0  ]   =   "555-9999"  ;  phone_book  [  "Салли Смарт"  ,   1  ]   =   "99 Sharp Way"  ;  phone_book  [  "Джон Доу"  ,   0  ]   =   "555-1212"  ;  phone_book  [  "Джон Доу"  ,   1  ]   =   "3 Нигма Драйв"  ;  phone_book  [  "Дж. Рэндом Хакер"  ,   0  ]   =   "555-1337"  ;  phone_book  [  "Дж. Рэндом Хакер"  ,   1  ]   =   "Массачусетс Авеню, 77"  ; 

Драйверы LPC, достаточно современные для поддержки конструкции foreach(), используют ее для перебора типов сопоставления.

В Lua «таблица» — это фундаментальный тип, который можно использовать либо как массив (числовой индекс, быстро), либо как ассоциативный массив.

Ключи и значения могут быть любого типа, кроме nil. Далее основное внимание уделяется нечисловым индексам.

Табличный литерал записывается как { value, key = value, [index] = value, ["non id string"] = value }. Например:

phone_book   =   { 	 [  "Салли Смарт"  ]   =   "555-9999"  ,  	 [  "Джон Доу"  ]   =   "555-1212"  ,  	 [  "Дж. Рэндом Хакер"  ]   =   "553-1337"  ,   -- Запятая допустима  }  aTable   =   { 	 -- Таблица как значение 	 subTable   =   {   5  ,   7.5  ,   k   =   true   },   -- ключ "subTable" 	 -- Функция как значение 	 [  'John Doe'  ]   =   функция   (  возраст  ),   если   возраст   <   18   , то   возврат   «Молодой»   иначе   вернет   «Старый!»   end   end  , 	 -- Таблица и функция (и другие типы) также могут использоваться в качестве ключей  } 

Если ключ является допустимым идентификатором (а не зарезервированным словом), кавычки можно опустить. Идентификаторы чувствительны к регистру.

Поиск записывается либо с использованием квадратных скобок, которые всегда работают, либо с помощью точечной записи, которая работает только для ключей-идентификаторов:

print  (  aTable  [  "Джон Доу"  ](  45  ))  x   =   aTable  .  подтаблица  .  к 

Вы также можете перебирать все ключи и связанные значения с помощью итераторов или циклов for:

simple   =   {   [  true  ]   =   1  ,   [  false  ]   =   0  ,   [  3.14  ]   =   math.pi  ,   x   =   'x'  ,   [  "!"  ]   =   42   }  function   FormatElement  (  key  ,   value  ) 	 return   "["   ..   tostring  (  key  )   ..   "] = "   ..   value   ..   ", "  end  — Итерация по всей  таблице  ключей .  foreach  (  simple  ,   function   (  k  ,   v  )   io.write  (  FormatElement  (  k  ,   v  ))   end  )  print  ""  для   k  ,   v   в   парах  (  простой  )   do   io.write  (  FormatElement  (  k  ,   v  ))   end  print  " "  k  =   nil  повторите 	 k  ,   v   =   next  (  simple  ,   k  ), 	 если   k   ~=   nil,   то   io.write  (  FormatElement  (  k  ,   v  ))   завершится  до тех пор, пока   k   ==   nil  print  "" 

Запись можно удалить, установив для нее значение nil:

простой  .  х   =   ноль 

Аналогичным образом вы можете перезаписать значения или добавить их:

простой  [  '%'  ]   =   "процент"  простой  [  '!'  ]   =   111 

Mathematica и язык Wolfram

[ редактировать ]

Mathematica и Wolfram Language используют выражение Association для представления ассоциативных массивов. [7]

 телефонная книга   =   <|   «Салли Смарт»   ->   «555-9999»  ,                   «Джон Доу»   ->   «555-1212»  ,                  «Дж. Рэндом Хакер»   ->   «553-1337»   |>  ; 

Чтобы получить доступ: [8]

 телефонная книга  [[  Клавиша  [  "Салли Смарт"  ]]] 

Если ключи являются строками, ключевое слово Key не требуется, поэтому:

 телефонная книга  [[  "Салли Смарт"  ]] 

Чтобы перечислить ключи: [9] и ценности [10]

Ключи[телефонная книга]Ценности[телефонная книга] 

В MUMPS каждый массив является ассоциативным. Встроенная прямая поддержка ассоциативных массивов на уровне языка.применяется к частным, специфичным для процесса массивам, хранящимся в памяти, называемым «локальными», а также к постоянным, общим, глобальным массивам, хранящимся на диске, которые доступны одновременно для нескольких заданий. Имени глобальных переменных предшествует циркумфлекс «^», чтобы отличить их от локальных переменных.

SET ^phonebook("Салли Смарт")="555-9999" ;; хранение постоянных данныхSET телефонная книга("Джон Доу")="555-1212" ;; хранение временных данныхSET телефонная книга("Дж. Рэндом Хакер")="553-1337" ;; хранение временных данныхОБЪЕДИНИТЬ ^phonebook=телефонная книга ;; копирование временных данных в постоянные данные 

Для доступа к значению элемента просто необходимо использовать имя с индексом:

НАПИШИТЕ «Номер телефона:»,^телефонная книга («Салли Смарт»),! 

Вы также можете перебрать связанный массив следующим образом:

НАЗВАНИЕ УСТАНОВКИ=""FOR S NAME=$ORDER(^телефонная книга(ИМЯ)) QUIT:NAME="" НАПИШИТЕ ИМЯ," Номер телефона:",^телефонная книга(ИМЯ),! 

Objective-C (Какао/GNUstep)

[ редактировать ]

Cocoa и GNUstep , написанные на Objective-C , обрабатывают ассоциативные массивы, используя NSMutableDictionary (изменяемая версия NSDictionary) кластер классов. Этот класс позволяет выполнять назначения между любыми двумя объектами. Копия ключевого объекта создается до его вставки в NSMutableDictionary, поэтому ключи должны соответствовать NSCopying протокол. При вставке в словарь объект значения получает сообщение сохранения, чтобы увеличить счетчик ссылок. Объект значения получит сообщение о выпуске, когда он будет удален из словаря (либо явно, либо путем добавления в словарь другого объекта с тем же ключом).

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"  ]; 

Для доступа к назначенным объектам можно использовать эту команду:

id   anObject   =   [  aDictionary   objectForKey  :  @"Салли Смарт"  ]; 

Все ключи или значения можно перечислить с помощью NSEnumerator:

NSEnumerator   *  keyEnumerator   =   [  aDictionary   keyEnumerator  ];  идентификационный   ключ  ;  while   ((  key   =   [  keyEnumerator   nextObject  ]))  {    // ... обработаем его здесь ...  } 

В Mac OS X 10.5+ и iPhone OS ключи словаря можно перечислить более кратко, используя команду NSFastEnumeration конструкция: [11]

for   (  id   key   в   aDictionary  )   {    // ... обработаем его здесь ...  } 

Что еще более практично, графы структурированных данных можно легко создать с помощью Cocoa , особенно NSDictionary ( NSMutableDictionary). Это можно проиллюстрировать этим компактным примером:

NSDictionary   *  aDictionary   =         [  NSDictionary   словарьWithObjectsAndKeys  :                             [  NSDictionary   словарьWithObjectsAndKeys  :                                     @"555-9999"  ,   @"Sally Smart"  ,                                     @"555-1212"  ,   @"John Doe"  ,                                     nil  ],   @"students"  ,                             [  NSDictionary   словарьWithObjectsAndKeys  :                                     @"553-1337"  ,   @"Случайный хакер"  ,                                     ноль  ],   @"хакеры"  ,                             ноль  ]; 

К соответствующим полям можно быстро получить доступ, используя ключевые пути:

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

Язык программирования OCaml предоставляет три различных ассоциативных контейнера. Самый простой — это список пар:

#   let   m   =   [ 	 "Салли Смарт"  ,   "555-9999"  ; 	 «Джон Доу»  ,   «555-1212»  ; 	 «Дж. Рэндом Хакер»  ,   «553-1337»  ];;  val   m   :   (  string   *   string  )   list   =   [ 	 (  "Салли Смарт"  ,   "555-9999"  ); 	 (  «Джон Доу»  ,   «555-1212»  ); 	 (  «Дж. Рэндом Хакер»  ,   «553-1337»  )  ]  #   Список  .  доц   "Джон Доу"   м  ;;  -   :   строка   =   "555-1212" 

Второй — полиморфная хеш-таблица:

#   пусть   m   =   Hashtbl  .  создать   3  ;;  val   m   :   (  '  _  a  ,   '  _  b  )   Hashtbl  .  t   =   <abstr>  #Hashtbl   .  добавьте   m   «Салли Смарт»   «555-9999»  ;    Хэштбл  .  добавьте   m   "Джон Доу"   "555-1212"  ;    Хэштбл  .  добавить   m   "J. Random Hacker"   "553-1337"  ;;  -   :   unit   =   ()  #   Hashtbl  .  найдите   m   "Джон Доу"  ;;  -   :   строка   =   "555-1212" 

В приведенном выше коде используется хеш-функция OCaml по умолчанию. Hashtbl.hash, который определяется автоматически для всех типов. Чтобы использовать модифицированную хеш-функцию, используйте интерфейс функтора Hashtbl.Make для создания модуля, например с помощью Map.

Наконец, функциональные карты (представленные в виде неизменяемых сбалансированных двоичных деревьев):

#   модуль   StringMap   =   Карта  .  Создать  (  Строка  );;  ...  #   пусть   m   =   StringMap  .  добавьте   «Салли Смарт»   «555-9999»   StringMap  .  пусто,    пусть   m   =   StringMap  .  добавьте   «Джон Доу»   «555-1212»   m    let   m   =   StringMap  .  добавить   "J. Random Hacker"   "553-1337"   м  ;;  val   m   :   строка   StringMap  .  t   =   <abstr>  #StringMap   .  найти   «Джона Доу»   м  ;;   -   :   строка   =   "555-1212" 

Обратите внимание, что для использования Map, вам необходимо предоставить функтор Map.Make с модулем, определяющим тип ключа и функцию сравнения. Сторонняя библиотека ExtLib предоставляет полиморфную версию функциональных карт, называемую PMap, [12] которому при создании предоставляется функция сравнения.

Списки пар и функциональные карты предоставляют чисто функциональный интерфейс. Напротив, хеш-таблицы предоставляют императивный интерфейс. Для многих операций хеш-таблицы выполняются значительно быстрее, чем списки пар и функциональные карты.

Язык программирования OptimJ является расширением Java 5. Как и Java, Optimj предоставляет карты; но OptimJ также предоставляет настоящие ассоциативные массивы. Массивы Java индексируются неотрицательными целыми числами; ассоциативные массивы индексируются ключами любого типа.

String  [  String  ]   phoneBook   =   {  "Салли Смарт"        ->   "555-9999"  ,  "Джон Доу"           ->   "555-1212"  ,  "Дж. Рэндом Хакер"   ->   "553-1337"  };  // String[String] — это не тип Java, а тип optimj:  // ассоциативный массив строк, индексированных строками.  // перебираем значения  for  (  String   Number   :   PhoneBook  )   {  System  .  вне  .  println  (  номер  );  }  // Предыдущий оператор печатает: "555-9999" "555-1212" "553-1337"  ключи  for  (  строки   Имя   :   phoneBook.keys  перебираем  //  )   {  System  .  вне  .  println  (  имя   +   " -> "   +   телефонная книга  [  имя  ]  );  }  // телефонная книга[имя] получает доступ к значению по ключу (это похоже на доступ к массиву Java)  // т.е. телефонная книга["Джон Доу"] возвращает "555-1212" 

Конечно, можно определять многомерные массивы, смешивать массивы Java и ассоциативные массивы, смешивать карты и ассоциативные массивы.

 int  [  строка  ][][  двойной  ]   a  ;   Ява  .  утилита  .  Map  <  String  [  Object  ]  ,   Integer  >   b  ; 

Perl 5 имеет встроенную поддержку ассоциативных массивов на уровне языка. Современный Perl называет ассоциативные массивы хэшами ; термин «ассоциативный массив» встречается в более старой документации, но считается несколько архаичным. Хэши Perl 5 плоские: ключи — это строки, а значения — скаляры. Однако значения могут быть ссылками на массивы или другие хеши, а стандартный модуль Perl 5 Tie::RefHash позволяет использовать хеши со ссылочными ключами.

Хэш-переменная помечается значком % sigil , чтобы отличить его от скалярных, массивных и других типов данных. Хэш-литерал — это список значений ключа, предпочтительной формой которого является Perl. => токен, который семантически по большей части идентичен запятой и делает связь ключ-значение более понятной:

my   %phone_book   =   ( 	 'Салли Смарт'        =>   '555-9999'  , 	 'Джон Доу'           =>   '555-1212'  , 	 'Дж. Рэндом Хакер'   =>   '553-1337'  ,  ); 

Для доступа к элементу хеша используется синтаксис $hash_name{$key} – ключ заключен в фигурные скобки , а имя хеша начинается с префикса $, указывая, что сам элемент хеша является скалярным значением, даже если он является частью хеша. Стоимость $phone_book{'John Doe'} является '555-1212'. % сигил используется только при обращении к хешу в целом, например, при запросе keys %phone_book.

Список ключей и значений можно извлечь с помощью встроенных функций. keys и values, соответственно. Так, например, чтобы напечатать все ключи хеша:

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

Можно перебирать пары (ключ, значение), используя each функция:

while   ((  $name  ,   $number  )   =   каждый   %phone_book  )   { 	 print   'Номер для'  ,   $name  ,   ':'  ,   $number  ,   "\n"  ;  } 

«Ссылка» хеша, которая представляет собой скалярное значение, указывающее на хеш, задается в буквальной форме с использованием фигурных скобок в качестве разделителей, а синтаксис в остальном аналогичен указанию литерала хеша:

my   $phone_book   =   { 	 'Салли Смарт'   =>   '555-9999'  , 	 'Джон Доу'   =>   '555-1212'  , 	 'Дж. Случайный хакер'   =>   '553-1337'  ,  }; 

Доступ к значениям в хэш-ссылке осуществляется с помощью оператора разыменования:

print   $phone_book  ->  {  'Салли Смарт'  }; 

Когда на хэш, содержащийся в ссылке на хеш, необходимо обращаться как единое целое, как в случае с keys функция, синтаксис следующий:

foreach   $name   (  keys   %  {  $phone_book  })   { 	 print   'Номер для'  ,   $name  ,   ':'  ,   $phone_book  ->  {  $name  },   "\n"  ;  } 

Перл 6 (Раку)

[ редактировать ]

Perl 6 , переименованный в «Raku», также имеет встроенную поддержку на уровне языка ассоциативных массивов, которые называются хэшами или объектами, выполняющими «ассоциативную» роль. Как и в Perl 5, хэши по умолчанию в Perl 6 являются плоскими: ключи представляют собой строки, а значения — скаляры. Можно определить хеш, чтобы не приводить все ключи к строкам автоматически: они называются «хешами объектов», поскольку ключи таких хэшей остаются исходным объектом, а не его строковой структурой.

Хэш-переменная обычно помечается знаком % sigil , чтобы визуально отличить его от скалярных, массивных и других типов данных, а также определить его поведение при итерации. Хэш-литерал — это список значений ключа, предпочтительной формой которого является Perl. => токен, который делает связь ключ-значение более понятной:

моя   %телефонная книга  =	 'Салли Смарт'  =>  '555-9999'  ,	 'Джон Доу'  =>  '555-1212'  ,	 'Дж. Случайный хакер'  =>  '553-1337'  ,; 

Для доступа к элементу хеша используется синтаксис %hash_name{$key} – ключ заключен в фигурные скобки и хеш-имя (обратите внимание, что сигила не меняется, в отличие от Perl 5). Стоимость %phone-book{'John Doe'} является '555-1212'.

Список ключей и значений можно извлечь с помощью встроенных функций. keys и values, соответственно. Так, например, чтобы напечатать все ключи хеша:

для   %телефонной книги  .  ключи  ->  $name  {	 скажи   $имя  ;} 

По умолчанию при переборе хеша получаются пары ключ-значение.

для   %телефонной книги  ->  $entry  {	 скажите   «Номер для $entry.key(): $entry.value()»  ;  # использование расширенных функций интерполяции } 

Также возможно получить чередующиеся значения ключей и значений, используя метод kv метод:

для   %телефонной книги  .  кв  ->  $имя  ,  $номер  {	 скажите   «Номер для $name: $number»  ;} 

У Раку нет никаких упоминаний. Хэши можно передавать как отдельные параметры, которые не сглаживаются. Если вы хотите убедиться, что подпрограмма принимает только хэши, используйте символ % в подписи.

подсписок   -телефонная книга  (  %pb  ) {     для   %pb  .  кв  ->  $имя  ,  $номер  {         скажите   «Номер для $name: $number»  ;    }} список-телефонная книга  (  % телефонная книга  ); 

В соответствии с постепенной типизацией хэши могут подвергаться ограничениям типа, ограничивая набор допустимых ключей определенным типом.

# Определить хэш, ключи которого могут быть только целыми числами (тип «Int»).  мой   %numbersWithNames  {  Int  }; # Ключи должны быть целыми числами, как в этом случае.  %numbersWithNames  .  нажать  (  1  =>  «один»  ); # Это вызовет ошибку, поскольку строки в качестве ключей недействительны.  %numbersWithNames  .  push  (  "ключ"  =>  "два"  ); 

. Встроенный тип массива PHP на самом деле является ассоциативным массивом Даже при использовании числовых индексов PHP внутренне хранит массивы как ассоциативные массивы. [13] Таким образом, PHP может иметь массивы с непоследовательной числовой индексацией. Ключи должны быть целочисленными (числа с плавающей запятой усекаются до целых) или строкового типа, а значения могут быть произвольными типами, включая другие массивы и объекты. Массивы неоднородны: в одном массиве могут быть ключи разных типов. Ассоциативные массивы PHP можно использовать для представления деревьев, списков, стеков, очередей и других распространенных структур данных, не встроенных в PHP.

Ассоциативный массив можно объявить, используя следующий синтаксис:

$телефонная книга                       =   массив  ();  $phonebook  [  'Салли Смарт'  ]        =   '555-9999'  ;  $phonebook  [  'Джон Доу'  ]           =   '555-1212'  ;  $телефонная книга  [  'Дж. Случайный хакер'  ]   =   '555-1337'  ;  // или  $phonebook   =   array  (      'Sally Smart'        =>   '555-9999'  ,      'John Doe'           =>   '555-1212'  ,      'J. Random Hacker'   =>   '555-1337'  ,  );  // или, начиная с PHP 5.4,  $phonebook   =   [      'Sally Smart'        =>   '555-9999'  ,      'John Doe'           =>   '555-1212'  ,      'J. Случайный хакер'   =>   '555-1337'  ,  ];  // или  $phonebook  [  'contacts'  ][  'Sally Smart'  ][  'number'  ]        =   '555-9999'  ;  $phonebook  [  'контакты'  ][  'Джон Доу'  ][  'номер'  ]           =   '555-1212'  ;  $phonebook  [  'контакты'  ][  'Дж. Случайный хакер'  ][  'номер'  ]   =   '555-1337'  ; 

PHP может перебирать ассоциативный массив следующим образом:

foreach   (  $phonebook   as   $name   =>   $number  )   {      echo   'Номер для'  ,   $name  ,   ':'  ,   $number  ,   "  \n  "  ;  }  // В последнем примере массива он используется следующим образом  foreach   (  $phonebook  [  'contacts'  ]   as   $name   =>   $num  )   {     echo   'Name: '  ,   $name  ,   ', Number: '  ,   $num  [  ' число'  ],   "  \n  "  ;  } 

PHP имеет обширный набор функций для работы с массивами. [14]

Ассоциативные массивы, которые могут использовать объекты в качестве ключей вместо строк и целых чисел, могут быть реализованы с помощью SplObjectStorage класс из стандартной библиотеки PHP (SPL). [15]

Pike имеет встроенную поддержку ассоциативных массивов, которые называются отображениями. Сопоставления создаются следующим образом:

сопоставление  (  строка  :  строка  )   телефонная книга   =   ([ 	 "Салли Смарт"  :  "555-9999"  , 	 "Джон Доу"  :  "555-1212"  , 	 "Дж. Рэндом Хакер"  :  "555-1337"  ]); 

Доступ и проверка присутствия в сопоставлениях осуществляется с помощью оператора индексации. Так phonebook["Sally Smart"] вернет строку "555-9999", и phonebook["John Smith"] вернул бы 0.

Итерация по отображению может быть выполнена с помощью foreach:

foreach  (  телефонная книга  ;   строковый   ключ  ;   строковое   значение  )   { 	 write  (  "%s:%s  \n  "  ,   ключ  ,   значение  );  } 

Или используя объект итератора:

Картирование  .  Итератор   i   =   get_iterator  (  телефонная книга  );  while   (  i  ->  index  ())   { 	 write  (  "%s:%s  \n  "  ,   i  ->  index  (),   i  ->  value  ()); 	 я  ->  следующий  ();  } 

Элементы сопоставления можно удалить с помощью m_delete, который возвращает значение удаленного индекса:

string   sallys_number   =   m_delete  (  телефонная книга  ,   «Салли Смарт»  ); 

Постскриптум

[ редактировать ]

В PostScript ассоциативные массивы называются словарями. В PostScript уровня 1 они должны создаваться явно, но на уровне 2 введено прямое объявление с использованием синтаксиса двойной угловой скобки:

  % Объявление уровня 1    3   dict   dup   start      /red     (rouge)   def      /green   (vert)    def      /blue    (bleu)    def    end    % Объявление уровня 2    <<      /red     (rot)      /green   (gruen)      /blue    (blue)    >>    % Оба метода оставляют словарь в стеке операндов 

Доступ к словарям можно получить напрямую, используя getили неявно, поместив словарь в стек словарей, используя begin:

  % Поскольку предыдущие два словаря все еще находятся в стеке операндов,    /red   get   print      % выводит 'rot'    start    green   print         % выводит 'vert'    end 

Содержимое словаря можно перебирать с помощью forall, хотя и не в каком-то определенном порядке:

  % Пример уровня 2    <<      /This    1      /That    2      /Other   3    >>   {  exch   =print   ( is )   print   ==  }   forall 

Что может вывести:

  Это    2    Это    1    Другое   это   3 

Словари можно дополнять (до определенного размера только на уровне 1) или изменять с помощью put, и записи можно удалить с помощью undef:

  % определить словарь для удобного повторного использования:    /MyDict   <<      /rouge   (красный)      /vert   (зеленый)    >>   def    % добавить в него    MyDict   /bleu   (синий)   положить    % изменить его    MyDict   /vert   (зеленый)   поставить    % удалить что-нибудь    MyDict   /румяна   undef 

Некоторые версии Пролога включают утилиты словаря («dict»). [16]

В Python ассоциативные массивы называются « словарями ». Словарные литералы ограничиваются фигурными скобками:

телефонная книга   =   {      "Салли Смарт"  :   "555-9999"  ,      "Джон Доу"  :   "555-1212"  ,      "Дж. Рэндом Хакер"  :   "553-1337"  ,  } 

Доступ к элементам словаря можно получить с помощью оператора индексации массива:

>>>   телефонная книга  [  "Салли Смарт"  ]  '555-9999' 

Цикл перебора всех ключей словаря:

>>>   для   ключа   в   телефонной книге  :  ...       распечатать  (  ключ  ,   книга  [  ключ  ])  Салли   Смарт   555  -  9999  J.  телефонная   Случайный   хакер   553–1337  Джон   Доу   555–1212 

Перебор кортежей (ключ, значение):

>>>   для   ключа  ,   значения   в   телефонной книге  .  элементы  :  ...       печать  (  ключ  ,   значение  )  Салли   Смарт   555  9999  J.  ( )   Случайный   хакер   553–1337  Джон   Доу   555–1212 

Ключи словаря можно удалить по отдельности с помощью del заявление. Соответствующее значение можно вернуть до удаления пары ключ-значение с помощью метода pop типа dict:

>>>   del   телефонная книга  [  "Джон Доу"  ]  >>>   val   =   телефонная книга  .  pop  (  «Салли Смарт»  )  >>>   телефонная книга  .  ключей  ()   # Остался только один ключ  [  'J. Случайный хакер'  ] 

Python 2.7 и 3.x также поддерживают понимание dict (аналогично пониманию списков ), компактный синтаксис для создания словаря из любого итератора:

>>>   Square_dict   =   {  i  :   i  *  i   для   i   в   диапазоне  (  5  )}  >>>   Square_dict  {  0  :   0  ,   1  :   1  ,   2  :   4  ,   3  :   9  ,   4  :   16  }  >>>   {  key  :   значение   ключа   книге  ,   значение   в   телефонной  .  items  (),   если   «J»   в   ключе  }  {  'J. Случайный хакер'  :   '553-1337'  ,   'Джон Доу'  :   '555-1212'  } 

Строго говоря, словарь представляет собой надмножество ассоциативного массива, поскольку ни ключи, ни значения не ограничиваются одним типом данных. Словарь можно представить как «ассоциативный список», используя номенклатуру Python. Например, следующее также является законным:

телефонная книга   =   {      "Салли Смарт"  :   "555-9999"  ,      "Джон Доу"  :   Нет  ,      "Дж. Рэндом Хакер"  :   -  3.32  ,      14  :   "555-3322"  ,  } 

Ключи словаря должны иметь неизменяемый тип данных. В Python строки неизменяемы из-за метода их реализации.

Красный встроенный map![17] datatype предоставляет ассоциативный массив, который сопоставляет значения типов слов, строк и скалярных ключей со значениями любого типа. Для поиска внутри используется хеш-таблица.

Карту можно записать в виде литерала, например #(key1 value1 key2 value2 ...)или может быть создан с помощью make map! [key1 value1 key2 value2 ...]:

Красный   [  Название:  "Моя карта"  ]  my-map:   создай   карту!   [      «Салли Смарт»        «555-9999»      «Джон Доу»           «555-1212»      «Дж. Рэндом Хакер»   «553-1337»  ]  ; Красный сохраняет регистр как для ключей, так и для значений, однако поиск по умолчанию нечувствителен к регистру; можно принудительно настроить чувствительность к регистру, используя уточнение <code>/case</code> для <code>select</code> и <code>put</code>.  ; Конечно, можно использовать значения <code>word!</code> в качестве ключей, и в этом случае обычно предпочтительнее использовать значения <code>set-word!</code> при создании карты, но любой тип слова может использоваться для поиска или создания.  моя-другая-карта:   создать   карту!   [  foo:   42   бар:   ложь  ]  ; Обратите внимание, что блок никак не сокращается и не оценивается, поэтому в приведенном выше примере ключ <code>bar</code> связан со словом <code>word!</code> <code>false</code>, а не с <code>word!</code> <code>false</code>. чем значение <code>logic!</code> false; если желательно последнее, можно использовать буквальный синтаксис:  my-other-map:   make   map!   [  foo:   42   bar:   #  [  false  ]]  ; или ключи можно добавить после создания:  my-other-map:   make   map!   [  foo:   42  ]  моя-другая-карта  /bar:   false ; Поиск можно записать с использованием нотации <code>path!</code> или с помощью действия <code>select</code>:  select   my-map   "Sally Smart"  my-other-map  /foo  ; Вы также можете перебрать все ключи и значения с помощью <code>foreach</code>:  foreach   [  ключа   значение  ]   my-map   [      print   [  ключ   «связан со»   значением  ]  ]  ; Ключ можно удалить с помощью <code>remove/key</code>:  удалить  /key   my-map   "Sally Smart" 

В REXX ассоциативные массивы называются «основными переменными» или «составными переменными».

КЛЮЧ   =   «Салли Смарт» ТЕЛЕФОННАЯ КНИГА  .  КЛЮЧ   =   '555-9999' KEY   =   «Джон Доу» ТЕЛЕФОННАЯ КНИГА  .  КЛЮЧ   =   '555-1212' КЛЮЧ   =   'Дж. Случайный хакер' ТЕЛЕФОННАЯ КНИГА  .  КЛЮЧ   =   '553-1337' 

Переменные-стержни с цифровыми ключами обычно начинаются с 1 и идут вверх. Переменная основы с нулевой клавишейпо соглашению содержит общее количество элементов в основе:

ИМЯ  .  1   =   «Салли Смарт» ИМЯ  .  2   =   «Джон Доу» ИМЯ  .  3   =   'Дж. Случайный хакер' ИМЯ  .  0   =   3 

В REXX нет простого способа автоматического доступа к ключам основной переменной; и обычноключи хранятся в отдельном ассоциативном массиве с числовыми ключами.

В Ruby хеш-таблица используется следующим образом:

телефонная книга   =   {    'Салли Смарт'   =>   '555-9999'  ,    'Джон Доу'   =>   '555-1212'  ,    'Дж. Случайный хакер'   =>   '553-1337'  }  телефонная книга  [  'Джон Доу'  ] 

Ruby поддерживает хэш-циклы и итерации со следующим синтаксисом:

irb(main):007:0>  ### перебираем ключи и значения  irb(main):008:0*  телефонная книга  .  каждый   {  |  ключ  ,   значение  |   помещает   ключ   +   " => "   +   значение  }  Салли Смарт => 555-9999  Джон Доу => 555-1212  Дж. Случайный Хакер => 553-1337  => {"Салли Смарт"=>"555-9999", "Джон Doe"=>"555-1212", "J. Random Hacker"=>"553-1337"}  irb(main):009:0>  ### перебирать только ключи  irb(main):010:0*  телефонная книга  .  каждый_ключ   {  |  ключ  |   помещает   ключ  }  Салли Смарт  Джон Доу  Дж. Рэндом Хакер  => {"Салли Смарт"=>"555-9999", "Джон Доу"=>"555-1212", "Дж. Рэндом Хакер"=>"553-1337 "}  irb(main):011:0>  ### перебирать только значения  irb(main):012:0*  телефонная книга  .  каждое_значение   {  |  ценность  |   помещает   значение  }  555-9999  555-1212  553-1337  => {"Салли Смарт"=>"555-9999", "Джон Доу"=>"555-1212", "Дж. Рэндом Хакер"=>"553- 1337"} 

Ruby также поддерживает множество других полезных операций с хэшами, таких как объединение хешей, выбор или отклонение элементов, соответствующих некоторым критериям, инвертирование (замена ключей и значений) и преобразование хеша в массив.

Ржавчина

[ редактировать ]

Стандартная библиотека Rust предоставляет хэш-карту ( std::collections::HashMap) и карту B-дерева ( std::collections::BTreeMap). Они используют несколько методов с одинаковыми именами, но имеют разные требования к типам вставляемых ключей. HashMap требуются ключи для реализации Eq ( отношение эквивалентности ) и Hash (хешируемость) и сохраняет записи в неопределенном порядке, а BTreeMap требует Ord ( общий порядок ) для своих ключей и сохраняет записи в порядке, определенном типом ключа. Порядок отражается итераторами по умолчанию.

используйте   std  ::  collections  ::  HashMap  ;  пусть   mut   phone_book   =   HashMap  ::  new  ();  телефонная_книга  .  вставка  (  «Салли Смарт»  ,   «555-9999»  );  телефонная_книга  .  вставить  (  "Джон Доу"  ,   "555-1212"  );  телефонная_книга  .  вставка  (  "Дж. Рэндом Хакер"  ,   "555-1337"  ); 

Итераторы по умолчанию посещают все записи как кортежи. HashMap итераторы посещают записи в неопределенном порядке, а BTreeMap итератор посещает записи в порядке, определенном типом ключа.

for   (  имя  ,   номер  )   в   &  phone_book   {      println!  (  "{} {}"  ,   имя  ,   номер  );  } 

Также существует итератор для ключей:

для   имени   в   телефонной книге  .  ключи  ()   {      println!  (  "{}"  ,   имя  );  } 

S-Lang имеет тип ассоциативного массива:

телефонная книга = Assoc_Type[];телефонная книга["Салли Смарт"] = "555-9999"телефонная книга["Джон Доу"] = "555-1212"телефонная книга["Дж. Рэндом Хакер"] = "555-1337" 

Вы также можете пройти через связанный массив несколькими способами:

имя foreach (телефонная книга) {	vmessage ("%s %s", имя, телефонная книга[имя]);} 

Чтобы напечатать отсортированный список, лучше воспользоваться сильными возможностями S-lang.поддержка стандартных массивов:

ключи = assoc_get_keys(телефонная книга);я = array_sort (ключи);vals = assoc_get_values(телефонная книга);array_map (Void_Type, &vmessage, "%s %s",keys[i],vals[i]); 

Scala предоставляет неизменяемый Map класс как часть scala.collection рамки:

val   телефонная книга   =   Карта  (  «Салли Смарт»   ->   «555-9999»  ,    «Джон Доу»   ->   «555-1212»  ,    «Дж. Рэндом Хакер»   ->   «553-1337»  ) 

Scala Вывод типа решит, что это Map[String, String]. Чтобы получить доступ к массиву:

телефонная книга  .  получить  (  «Салли Смарт»  ) 

Это возвращает Option type, эквивалент монады Maybe в Haskell в Scala.

В Smalltalk Dictionary используется:

телефонная книга   :=   Словарь   новый  .  в телефонной книге   :   «Салли Смарт»   введите:   «555-9999»  .  в телефонной книге   :   «Джон Доу»   введите:   «555-1212»  .  телефонная книга   по адресу:   'J. Случайный хакер»   поставил:   «553-1337»  . 

Чтобы получить доступ к записи, отправьте сообщение #at: отправляется в объект словаря:

телефонная книга   :   «Салли Смарт» 

Что дает:

 '555-9999' 

Словарь хеширует или сравнивает на основе равенства и помечает как ключ, так и значение как сильные ссылки . Существуют варианты, в которых хэширование/сравнение идентификаторов (IdentityDictionary) или сохранение слабых ссылок (WeakKeyDictionary/WeakValueDictionary).Поскольку каждый объект реализует #hash, любой объект можно использовать в качестве ключа (и, конечно же, как значения).

SNOBOL — один из первых (если не первый) языков программирования, использующих ассоциативные массивы. Ассоциативные массивы в СНОБОЛЕ называются Таблицами.

ТЕЛЕФОННАЯ КНИГА   =   ТАБЛИЦА  ()  ТЕЛЕФОННАЯ КНИГА  [  'Салли Смарт'  ]   =   '555-9999'  ТЕЛЕФОННАЯ КНИГА  [  'Джон Доу'  ]   =   '555-1212'  ТЕЛЕФОННАЯ КНИГА  [  'Дж. Случайный хакер'  ]   =   '553-1337' 

Стандартный ML

[ редактировать ]

Стандарт SML'97 языка программирования Standard ML не предоставляет никаких ассоциативных контейнеров. Однако различные реализации Standard ML предоставляют ассоциативные контейнеры.

Библиотека популярной реализации Standard ML of New Jersey (SML/NJ) предоставляет подпись (что-то вроде «интерфейса»), ORD_MAP, который определяет общий интерфейс для упорядоченных функциональных (неизменяемых) ассоциативных массивов. Существует несколько общих функторов: BinaryMapFn, ListMapFn, RedBlackMapFn, и SplayMapFn— которые позволяют создать соответствующий тип упорядоченной карты (типы — самобалансирующееся двоичное дерево поиска , отсортированный список ассоциаций , красно-черное дерево и дерево расширения соответственно), используя предоставленную пользователем структуру для описания типа ключа и компаратор. Функтор возвращает структуру в соответствии с ORD_MAP интерфейс. Кроме того, существует два предопределенных модуля для ассоциативных массивов, использующих целочисленные ключи: IntBinaryMap и IntListMap.

-   структура   StringMap   =   BinaryMapFn   (  структуры                                         тип   ord_key   =   string                                         val   Compare   =   String  .  Compare                                       End  );  структура   StringMap   :   ORD_MAP  -   val   m   =   StringMap  .  вставить   (  StringMap  .  пустой  ,   «Салли Смарт»  ,   «555-9999»  )    val   m   =   StringMap  .  вставить   (  m  ,   «Джон Доу»  ,   «555-1212»  )    val   m   =   StringMap  .  вставка   (  м  ,   «Дж. Рэндом Хакер»  ,   «553-1337»  );  val   m   =    T      {  cnt  =  3  ,  key  =  «Джон Доу»  ,       left  =  T   {  cnt  =  1  ,  key  =  «J. Random Hacker»  ,  left  =  E  ,  right  =  E  ,  value  =  «553-1337»  },       right  =  T   {  cnt  =  1  ,  key  =  "Салли Смарт"  ,  left  =  E  ,  right  =  E  ,  value  =  "555-9999"  },       value  =  "555-1212"  }   :   string   StringMap  .  карта   Стрингмап  .  найти   (  m  ,   «Джон Доу»  );  val   it   =   SOME   "555-1212"   :   строковый   параметр 

SML/NJ также предоставляет полиморфную хэш-таблицу:

-   исключение   NotFound  ;  исключение   NotFound  -   val   m   :   (  строка  ,   строка  )   HashTable  .  hash_table   =   Хэш-таблица  .  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  ,  НОЛЬ  ,  НОЛЬ  ,...  |  ]}    :   (  строка  ,  строка  )   HashTable  .  hash_table   Хэш-таблица  .  вставьте   m   (  «Салли Смарт»  ,   «555-9999»  );  val   it   =   ()   :   unit  -   HashTable  .  вставьте   m   (  «Джон Доу»  ,   «555-1212»  );  val   it   =   ()   :   unit  -   HashTable  .  вставьте   m   (  "J.Random Hacker"  ,   "553-1337"  );  val   it   =   ()   :   unit  HashTable  .  найти   «   Джон Доу»  ;   (* возвращает NONE, если не найден *)  val   it   =   SOME   "555-1212"   :   строковый   параметр  -   HashTable  .  поиск   m   "Джон Доу"  ;   (* вызывает исключение, если оно не найдено *)  val   it   =   "555-1212"   :   строка 

Также поддерживаются мономорфные хеш-таблицы с использованием HashTableFn функтор.

Другая реализация Standard ML, Moscow ML , также предоставляет некоторые ассоциативные контейнеры. Во-первых, он предоставляет полиморфные хеш-таблицы в Polyhash структура. Кроме того, некоторые функциональные карты из библиотеки SML/NJ, указанной выше, доступны как Binarymap, Splaymap, и Intmap структуры.

Существует два средства Tcl , которые поддерживают семантику ассоциативных массивов. «Массив» — это набор переменных. «Дикт» — это полная реализация ассоциативных массивов.

множество

[ редактировать ]
set   {  книга  (  Салли   Смарт  }   555–9999  )  $  set   john   {  Джон   Доу  }  set   телефонная  (  john  )   555–1212  книга  телефонная  set   {  книга  (  J.   Random   Hacker  )   553–1337  телефонная  } 

Если в имени переменной есть пробел, имя необходимо сгруппировать либо с помощью фигурных скобок (подстановка не производится), либо двойных кавычек (подстановка выполняется).

Альтернативно, несколько элементов массива могут быть установлены одной командой, представляя их сопоставления в виде списка (слова, содержащие пробелы, заключаются в скобки):

 массивов   набора  телефонная книга   [  список   {  Салли   Смарт  }   555  –  9999   {  Джон   Доу  }   555  –  1212   {  Дж.   Рэндом   Хакер  }   553  –  1337  ] 

Чтобы получить доступ к одной записи массива и поместить ее в стандартный вывод:

помещает   $телефонную книгу  (  Салли  \   Смарт  ) 

Что возвращает этот результат:

555-9999 

Чтобы получить весь массив как словарь:

массив   получить   телефонную книгу 

Результатом может быть (порядок ключей не указан не потому, что словарь неупорядочен, а потому, что массив):

{  Салли   Смарт  }   555-9999   {  Дж   Рэндом   Хакер  }   553-1337   {  Джон   Доу  }   555-1212  . 

диктовать

[ редактировать ]
установить   телефонную книгу   [  dict   create   {  Салли   Смарт  }   555  -  9999   {  Джон   Доу  }   555  -  1212   {  Дж.   Рэндом   Хакер  }   553  -  1337  ] 

Чтобы найти элемент:

dict   получить   $телефонную книгу   {  Джон   Доу  } 

Чтобы перебрать dict:

foreach   {  имя   номер  }   $phonebook   { 	 puts   "name: $name\nnumber: $number"  } 

Визуальный Бейсик

[ редактировать ]

Visual Basic может использовать класс Dictionary из среды выполнения сценариев Microsoft (которая поставляется с Visual Basic 6). Не существует стандартной реализации, общей для всех версий:

'Требуется ссылка на SCRRUN.DLL в свойствах проекта  . Dim   телефонная книга   как   новая   словаря  телефонная книга  .  Добавьте   «Салли Смарт»  ,   «555-9999»  телефонную книгу  .  Item  (  "John Doe"  )   =   "555-1212"  телефонная книга  (  "J. Random Hacker"  )   =   "553-1337"  Для   каждого   имени   в   телефонной книге 	 MsgBox   name   &   "="   &   phoneBook  (  name  )  Далее 

Визуальный Бейсик .NET

[ редактировать ]

Visual Basic .NET использует классы коллекций, предоставляемые .NET Framework .

Создание

[ редактировать ]

Следующий код демонстрирует создание и заполнение словаря ( см. в примере C# на этой странице дополнительную информацию ):

Dim   dic   как   новая   система  .  Коллекции  .  Общий  .  Словарь  (  Строки   ,   Строки  )  dic  .  Добавьте  (  «Салли Смарт»  ,   «555-9999»  )  dic  (  «Джон Доу»  )   =   «555-1212»  dic  .  Предмет  (  «Дж. Рэндом Хакер»  )   =   «553-1337» 

Альтернативным синтаксисом было бы использование инициализатора коллекции , который компилируется в отдельные вызовы Add:

Dim   dic   как   новая   система  .  Коллекции  .  Словарь  (  String   {  ,   String  )   From   {      {  "Салли Смарт"  ,   "555-9999"  },      "  Джон Доу"  ,   "555-1212"  },      {  "Дж. Рэндом Хакер"  ,   "553-1337"  }  } 

Доступ по ключу

[ редактировать ]

Пример, демонстрирующий доступ (см. Доступ к C# ):

Dim   sallyNumber   =   dic  (  «Салли Смарт»  )  ' или  Dim   sallyNumber   =   dic  .  Предмет  (  «Салли Смарт»  ) 
Тусклый   результат   As   String   =   Ничего  Тусклый   sallyNumber   =   If  (  dic  .  TryGetValue  (  «Sally Smart»  ,   result  ),   result  ,   «n/a»  ) 

Перечисление

[ редактировать ]

Пример, демонстрирующий перечисление (см. #C# перечисление ):

' просматриваем коллекцию и отображаем каждую запись.  Для   каждого   kvp   как   KeyValuePair  (  String   ,   String  )   в   dic      Console  .  WriteLine  (  "Номер телефона для {0}: {1}"  ,   kvp  .  Key  ,   kvp  .  Value  )  Далее 

Windows PowerShell

[ редактировать ]

В отличие от многих других интерпретаторов командной строки , Windows PowerShell имеет встроенную поддержку на уровне языка для определения ассоциативных массивов:

$phonebook   =   @{          'Салли Смарт'   =   '555-9999'  ; 	 «Джон Доу»   =   «555-1212»  ;  	 'Дж. Случайный хакер'   =   '553-1337'  } 

Как и в JavaScript, если имя свойства является допустимым идентификатором, кавычки можно опустить:

$myOtherObject   =   @{   foo   =   42  ;   бар   =   $false   } 

Записи могут быть разделены точкой с запятой или новой строкой:

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

Ключи и значения могут быть .NET объектами любого типа :

$now   =   [DateTime]  ::  Сейчас  $tomorrow   =   $now  .  AddDays  (  1  )  $ProcessDeletionSchedule   =   @{           (  Get-Process   блокнот  )   =   $now           (  Get-Process   Calc  )   =   $tomorrow  } 

Также возможно создать пустой ассоциативный массив и позже добавить к нему отдельные записи или даже другие ассоциативные массивы:

$phonebook   =   @{}  $phonebook   +=   @{   'Sally Smart'   =   '555-9999'   }  $phonebook   +=   @{   'John Doe'   =   '555-1212'  ;   'Дж. Случайный хакер'   =   '553-1337'   } 

Новые записи также можно добавлять с помощью оператора индекса массива, оператора свойства или оператора Add() метод базового объекта .NET:

$phonebook   =   @{}  $phonebook  [  'Салли Смарт'  ]   =   '555-9999'  $phonebook  .  'Джон Доу'   =   '555-1212'  $phonebook  .  Добавить  (  «Дж. Рэндом Хакер»  ,   «553-1337»  ) 

Чтобы разыменовать назначенные объекты, используйте оператор индекса массива, оператор свойства или параметризованное свойство. Item() объекта .NET можно использовать:

$phonebook  [  'Салли Смарт'  ]   $phonebook  .  "Джон Доу"  Телефонная книга  .  Предмет  (  «Дж. Рэндом Хакер»  ) 

Вы можете перебрать ассоциативный массив следующим образом:

$ телефонная книга  .  Ключи   |   foreach   {   "Номер для {0}: {1}"   -f   $_  ,  $phonebook  .  $_   } 

Запись можно удалить с помощью Remove() метод базового объекта .NET:

$ телефонная книга  .  Удалить  (  «Салли Смарт»  ) 

Хэш-таблицы могут быть добавлены:

$хэш1   =   @{   а  =  1  ;   б  =  2   }  $hash2   =   @{   c  =  3  ;   d  =  4   }  $hash3   =   $hash1   +   $hash2 

Поддержка форматов сериализации данных

[ редактировать ]

Многие форматы сериализации данных также поддерживают ассоциативные массивы (см. эту таблицу ).

В JSON ассоциативные массивы также называются объектами. Ключи могут быть только строками.

{      «Салли Смарт»  :   «555-9999»  ,      «Джон Доу»  :   «555-1212»  ,      «Дж. Рэндом Хакер»  :   «555-1337»  } 

Ассоциативные массивы YAML также называются элементами карты или парами ключ-значение. YAML не накладывает ограничений на типы ключей; в частности, они не ограничиваются скалярными или строковыми значениями.

Салли Смарт  :   555-9999  Джон Доу  :   555-1212  Дж. Рэндом Хакер  :   555-1337 
  1. ^ здесь , заархивировано здесь , исходный код доступен здесь . POSIX 1003.1-2001 описывает функции hcreate(), hdestroy() и hsearch()
  2. ^ «uthash: хеш-таблица для структур C» . Гитхаб . Проверено 3 августа 2020 г.
  3. ^ «Хеш-таблицы» . Гном-разработчик . Проверено 3 августа 2020 г.
  4. ^ «Ассоциативные массивы — язык программирования D» . dlang.org . Проверено 7 мая 2021 г.
  5. ^ «Эрланг — карты» . erlang.org . Проверено 7 марта 2021 г.
  6. ^ «Язык Common Lisp, 2-е издание: 15.6. Списки ассоциаций» . Университет Карнеги-Меллон . Проверено 3 августа 2020 г.
  7. ^ «Ассоциация (<-...->) — документация Wolfram Language» . ссылка.wolfram.com .
  8. ^ «Ключ — документация на языке Wolfram» . ссылка.wolfram.com .
  9. ^ «Ключи — документация на языке Wolfram» . ссылка.wolfram.com .
  10. ^ «Значения — документация на языке Wolfram» . ссылка.wolfram.com .
  11. ^ «Справочник по протоколу NSFastEnumeration» . Библиотека разработчиков Mac . 2011. Архивировано из оригинала 13 марта 2016 года . Проверено 3 августа 2020 г.
  12. ^ «Модуль PMap» . Ocaml-extlib . 2008. Архивировано из оригинала 11 декабря 2008 года . Проверено 3 августа 2020 г.
  13. ^ О реализации массивов в PHP.
  14. ^ «Массивы» . PHP.net . Проверено 3 августа 2020 г.
  15. ^ «Класс SplObjectStorage» . PHP.net . Проверено 3 августа 2020 г.
  16. ^ «Dicts: структуры с именованными аргументами»
  17. ^ «Карта! Тип данных» . doc.red-lang.org .
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: f7703b5baa2e115162200b460717fce4__1722246420
URL1:https://arc.ask3.ru/arc/aa/f7/e4/f7703b5baa2e115162200b460717fce4.html
Заголовок, (Title) документа по адресу, URL1:
Comparison of programming languages (associative array) - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)