LINUX.ORG.RU

Associative Array

 


0

1

Привет, ребят. Подскажите, пожалуйста, как можно сделать так, чтобы в Associative Array могли появляться повторяющаяся пара key-value, т.е. с одинаковым key и соответствующее ему value?

Предполагается, что ассоциативный массив не может хранить две пары с одинаковыми ключами. 
vvn_black ★★★★★
()
Ответ на: комментарий от IvanRia

Просто у меня происходит override, когда дублируется key-value в пользу последней пары, а мне как раз нужно чтобы не было override и всё повторяющееся осталось в массиве

VladSpider
() автор топика

А как ты хочешь значение забирать потом по ключу? Какое тебе возвращать - первое или второе? Похоже, тебе нужны оба, вот и решение напраш вается - храни оба по одному ключу тем или иным способом. То есть перед добавлением, проверь есть ли там такое уже и, если есть, забери значение, приплюсуй к своему и запиши сумму под этим же ключом.

pihter ★★★★★
()
Ответ на: комментарий от VladSpider

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

vvn_black ★★★★★
()

чтобы в Associative Array могли появляться повторяющаяся пара key-value, т.е. с одинаковым key и соответствующее ему value

Что будет, если в словаре есть «key»:«value1», а ты добавляешь туда «key»:«value2»? Что будет, если в словаре три копии «key»:«value1», а ты добавляешь туда «key»:«value2»?

i-rinat ★★★★★
()

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

arr[1,0]='hello'
arr[2,0]='world'
arr[3,0]='!'

UPD. В принципе можно и по ключу выборку сделать таким образом. Прикидываешь примерное максимальное кол-во возможных повторений ключей и в отдельной функции делаешь свой поиск в цикле по ключу с подстановкой индекса счётчика в качестве префикса.

Или ещё лучше - цикл от 0 до тех пор пока ключ не существует.

lnx4
()
Последнее исправление: lnx4 (всего исправлений: 3)
Ответ на: комментарий от VladSpider

Тебе хочется очень странного. Это, конечно, можно реализовать и на баше, но ты точно хочешь отлаживать вот такое:

#!/bin/bash

TEST="key_a=1 key_b=2 key_c=3 key_b=4"
declare -A arr_keys
declare -A arr_values

for ITER in $TEST ; do
  KEY=${ITER%=*}
  VALUE=${ITER#*=}
  if [[ -z ${arr_keys[$KEY]} ]] ; then
    arr_keys[$KEY]=1
  else
    let $((arr_keys[$KEY]++))
  fi
  arr_values[$KEY${arr_keys[$KEY]}]=$VALUE
done

echo "TEST: $TEST"
for KEY in ${!arr_keys[*]} ; do
  echo -n "$KEY = ( "
  for ITER in `seq 1 ${arr_keys[$KEY]}` ; do
    echo -n "${arr_values[$KEY$ITER]} "
  done
  echo ")"
done
?

gremlin_the_red ★★★★★
()

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

arr["$key"]+=" $value"
JaM
()
Ответ на: комментарий от gremlin_the_red

$KEY${arr_keys[$KEY]} могут пересекаться, например, 11 значений ключа a и ключ a1. По хорошему, вместо $KEY тут бы хэш от него использовать, но в баше встроенного хэша нет (или есть?), а вызывать каждый раз программу для его расчёта - это уже лютое извращение.

JaM
()
Ответ на: комментарий от gremlin_the_red

Плюсую. Это уже не ассоциативный массив, а довольно хитрый разбор строки. Я бы не стал городить подобную конструкцию в здравом уме.

shell-script ★★★★★
()
Ответ на: комментарий от JaM

Если я правильно тебя понимаю, ты предлагаешь ключи генерить на лету для каждого значения. Но в чём тогда смысл? Ты же не будешь знать каким конкретно ключам будут принадлежать конкретные значения. Хеш или что-то подобное не помогут в случае если попадутся одинаковые значение - тут мы вернёмся к изначально проблеме с повторяющимися ключами.

Ну и опять же - смысл? Зачем тебе эти уникальные ключи, если ты про них ничего заранее не знаешь?

shell-script ★★★★★
()
Последнее исправление: shell-script (всего исправлений: 1)
Ответ на: комментарий от shell-script

Ты в своём решении сделал два массива: arr_keys, где хранятся счётчики, и arr_values со значениями. Но ключи для arr_values ты получаешь добавлением номера к исходному ключу. В результате, например, ключ «k11» для arr_values может получится как для одиннадцатого значения исходного ключа «k», так и для первого значения исходного ключа «k1». Чтобы избежать такой коллизии можно ключи для arr_values получать добавлением номера не к исходному ключу, а к его хэшу.

JaM
()
Ответ на: комментарий от shell-script

Тьфу, блин, я про решение гремлина выше )

JaM
()
Ответ на: комментарий от vvn_black

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

+100500

Psilocybe ★★★★
()
Ответ на: комментарий от gremlin_the_red

Действительно. И на баше элементарно делается… Затупил я.

JaM
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.