# Which is a better way to write an "add or initialize"?

1. Dec 31, 2015

### SlurrerOfSpeech

In my work I often find myself having to write a procedure for

"If this key is in the map, push this element to the end of the array associated with the key; otherwise, add the key and an associated array whose single element is this one".

I used to do this like

Code (Text):

if ( key in M ) { M[key].push(elem); }
else { M[key] = [elem]; }

but now prefer to write it like

Code (Text):

if ( !(key in M ) { M.[key] = new Array(); }
M[key].push(elem);

Why do I like this new way if the old way is equivalent???

Because I like as few conditional blocks as possible. I like to think in terms of "If not this, change that fact and move on to the same logic we will always move on to" rather than "If not this, enter a different block of logic".

Note: I labeled this question as JavaScript only because I had to choose a label. My code is in JavaScript, but this question can apply to other languages.

2. Dec 31, 2015

### Filip Larsen

When initialization and adding can be separated (not always the case for all data structures) then your second approach is quite common and, in my opinion, a bit more clear than the former approach. I would go with the later approach whenever possible.

Note, that in JavaScript there is another common idiom when initializing and adding that uses the or-operator. Provided that your M object only have array members, then in your case that idiom would be like
Code (Text):

(M[key] || (M[key] = [])).push(elem);

3. Dec 31, 2015

### D H

Staff Emeritus
In this case, the difference is so small that it's a bit moot. How one would accomplish that is also language-dependent.

In python, I'd probably follow the mantra that it's easier to ask for forgiveness:
Code (Python):
def add_element (M, key, elem) :
try :
M[key].append (elem)
except KeyError :
M[key] = [elem]
In perl, I'd use something similar to your new method, except I'd use an end-line conditional, and to avoid not, I'd use unless:
Code (Perl):
sub add_element($$) { my (M, key, elem) = @_; M->{key} = [] unless exists M->{key}; push @{M->{key}}, elem; } Update on the above: @Filip Larsen's approach also works nicely in perl: Code (Perl): sub add_element($$$) { my ($M, $key,$elem) = @_;
push @{$M->{$key} or $M->{$key} = []}, \$elem;
}
In C++, I'd use the fact that M[key] automatically adds the key to the associative array if it's not present:
Code (C):
template <KeyType, ElemType>
std::unordered_map<KeyType, std::vector<ElemType>>& M,
const KeyType& key,
const ElemType& elem)
{
M[key].append(elem);
}

Last edited: Dec 31, 2015
4. Dec 31, 2015

### Filip Larsen

Now DH has started on other languages I may add that in C# (where the standard dictionary index operator getter throws exception on unknown keys) I mostly end up do something like

Code (Text):

void AddElement<TKey,TValue>(IDictionary<TKey,ICollection<TValue>> map, TKey key, TValue value)
{
ICollection<TValue> values;
if (!map.TryGet(key, out values)) {
map[key] = values = new List<TValue>();
}