从两个不同长度的数组中成对添加元素

时间:2017-03-03 14:47:26

标签: arrays bash shell

我正试图找出一种方法将两个数组的每个元素组合在一起。

例如:

list1=(1 2 3 4 5)    
list2=(32 45 5443 543 332 9889797)

输出:

33
47
5446
547
337
9889797

请注意,一个数组可能比另一个数组长。

这是我所需要的,但是,当第二个数组比第一个数组长时,它会失败。

list=(1 2 3 4 5)

list2=(32 45 5443 543 332 9889797)

x=0

for i in "${list[@]}"
do
    value1=$i
    value2="${list2[x]}"
    echo $((value1 + value2))
    x=$(($x + 1))
done

4 个答案:

答案 0 :(得分:2)

如果您不知道先前哪个数组会更长,请直接迭代两者的索引:

# generate sum for all indices in a *or* b
declare -A finished=( )                # track which indices we've already added
for idx in "${!a[@]}" "${!b[@]}"; do   # iterate over indices from *both* arrays
  [[ ${finished[$idx]} ]] && continue  # skip anything tracked as finished
  printf '%s\n' "$idx => $(( ${a[$idx]:-0} + ${b[$idx]:-0} ))"
  finished[$idx]=1
done

这适用于所有种类的数组,包括稀疏数组或关联数组,只要数组中使用的索引 a b 匹配。

让我们举个例子:

 #    0  1  2  3  4  5  6  7  8   ## indices
 a=(  1  2  3  4  5  6  7  8  9 )
 b=( 10 20 30 40 50 60 70 80 90 )

 # remove "3", at index 2, from array a
 unset a[2]

现在,在unset a[2]运行之后,a中的最高索引仍为8,但${#a[@]}8而不是7 };最高索引小于数组中条目数的规则被破坏。

然而,这个答案仍然有效:

0 => 11
1 => 22
3 => 44
4 => 55
5 => 66
6 => 77
7 => 88
8 => 99
2 => 30

我们仍然将330的索引值对齐,并将2中缺席的元素a视为0。

运行时:

declare -A a=( [foo]=1 [bar]=1 [baz]=1 ) b=( [bar]=1 [baz]=1 [qux]=1 )

...这会发出:

bar => 2
baz => 2
foo => 1
qux => 1

举一个具体的例子说明这种情况有效并且许多其他答案都没有:

a=( [10234]=20 [25432]=30 )
b=( [10234]=1  [25432]=2  )

...结果是正确的:

10234 => 21
25432 => 32

另一个:

declare -A a=( [bob]=20 [jim]=30 )
declare -A b=( [bob]=1  [jim]=2  )

和正确的结果:

bob => 21
jim => 32

我在上面打印索引是为了更详细地说明代码在幕后做什么,但当然你可以从格式字符串中删除$idx =>以排除它们。

答案 1 :(得分:1)

a=(4 5 3 2 6 2)
b=(7 5 3 4 6)

for ((i=0; i<${#a[@]} || i<${#b[@]}; i++)); do echo $((a[i] + b[i])); done

的产率:

11
10
6
6
12
2

使用b=(7 5 3 4 6 9 9 9 9)产生:

11
10
6
6
12
11
9
9
9

答案 2 :(得分:0)

如果你遍历较长的数组,那应该有效:

list=(1 2 3 4 5)
list2=(32 45 5443 543 332 9889797)
x=0

for i in "${list2[@]}"
do
 value1=$i
 value2="${list[x]}"
 echo $((value1 + value2))
 x=$(($x + 1))
done

答案 3 :(得分:0)

我不确定我为什么这么难?只需获取每个数组的长度,并使用较短数组的索引。

list1=(1 2 3 4 5)
list2=(32 45 5443 543 332 9889797)

a1_len=${#list1[*]}
a2_len=${#list2[*]}

if (( a1_len > a2_len ))
then
    short_arr=("${list2[@]}")
    long_arr=("${list1[@]}")
    (( diff = a2_len - 1 ))
else
    short_arr=("${list1[@]}")
    long_arr=("${list2[@]}")
    (( diff = a1_len - 1 ))
fi

for i in ${!short_arr[*]}
do
    out_arr+=($((${short_arr[i]} + ${long_arr[i]})))
done

out_arr+=(${long_arr[@]:$diff})

echo "${out_arr[@]}"