Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Duplicating an array 1:1 in zsh

Tags:

zsh

Although it seems fairly simple, there is a small nuance to the obvious solution.

The following code would cover most situations:

arr_1=(1 2 3 4)
arr_2=($arr_1)

However, empty strings do not copy over. The following code:

arr_1=('' '' 3 4)
arr_2=($arr_1)
print -l \
  "Array 1 size: $#arr_1" \
  "Array 2 size: $#arr_2"

will yield:

Array 1 size: 4
Array 2 size: 2

How would I go about getting a true copy of an array?

like image 223
wuffie Avatar asked Sep 03 '25 13:09

wuffie


1 Answers

It would be an "Array Subscripts" issue, so you could properly specify an array subscript form to select all elements of an array ($arr_1 for instance) within double quotes:

arr_1=('' '' 3 4)
arr_2=("${arr_1[@]}")
#=> arr_2=("" "" "3" "4")

Each elements of $arr_1 would be properly surrounded with double quotes even if it is empty.

A subscript of the form ‘[*]’ or ‘[@]’ evaluates to all elements of an array; there is no difference between the two except when they appear within double quotes.
‘"$foo[*]"’ evaluates to ‘"$foo[1] $foo[2] ..."’, whereas ‘"$foo[@]"’ evaluates to ‘"$foo[1]" "$foo[2]" ...’.
...
When an array parameter is referenced as ‘$name’ (with no subscript) it evaluates to ‘$name[*]’,

-- Array Subscripts, zshparam(1)

And empty elements of arrays will be removed according to "Empty argument removal", so

arr_2=($arr_1)
#=> arr_2=(${arr_1[*]})
#=> arr_2=(3 4)

Above behavior is not good in this case.

24. Empty argument removal
If the substitution does not appear in double quotes, any resulting zero-length argument, whether from a scalar or an element of an array, is elided from the list of arguments inserted into the command line.

-- Empty argument removal, Rules Expansion zshexpn(1)

like image 105
hchbaw Avatar answered Sep 05 '25 16:09

hchbaw