1

What would be the bash code after:

declare -A map

to do the following:

1) if a string does not yet exist in the map, create the entry for it and set its count (value) to 1

2) if the string already exists in the map, increment the count (value) by 1?

Am using post version 4.0 of Bash.

Based on @that other guy's answer, I tried:

#!/bin/bash
input=("a" "b" "a")
declare -a map

for i in ${input[@]}
do
  let 'map[$i]++'
  echo "map[$i]=${map[$i]}"
done

And when run it produces the following -- does NOT seem to work:

$ maptest
map[a]=1
map[b]=2
map[a]=3
2
  • declare -a map declares map to be a list (i.e. indexed by integers). It's not the same as declare -A map, which does create an associative array. Commented Aug 18, 2015 at 2:54
  • Thanks @rici. I was wrong on my version of Bash (from cygwin, it's 3.1.17, even though I just got cygwin installed.) Commented Aug 18, 2015 at 17:48

2 Answers 2

2

The way to do this would be:

let '++map[$key]'

This relies on the fact that an unset value is considered 0.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, am trying what you said with an echo statement that is obviously wrong, using: for i in ${input[@]} do let 'map[$i]++' echo "map[$i]=$map[$i]" done
@Ray In your question you said declare -A map while in your example you use declare -a map.
I see. I actually do have Bash 3.1.17. I falsely assumed that loading latest cygwin would give me a Bash shell that was more recent than 7+ years old. I might rev that but other part of team will be using the script. Is it possible that you edit your answer, just slightly change the text?
Sorry, that was confusing. I need you to edit the text just so I can award you point and mark it as an answer. Any slight text edit will do. Thanks.
0

The code sample in the (edited) question works correctly when used with declare -A instead of declare -a. So the accepted answer is correct.

However if used with set -u aka set -o nounset, it will fail with map: unbound variable

The solution is to use declare -iA and the += operator, like this:

#!/bin/bash
set -o nounset

input=("a" "b" "a")
declare -iA map

for i in ${input[@]}
do
  map[$i]+=1
  echo "map[$i]=${map[$i]}"
done

Which produces the following output:

map[a]=1
map[b]=1
map[a]=2

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.