如何根据我在Bash中预定义的列表对数组顺序进行排序。
我预定义的列表
fixed=(john doe mary ben)
我希望它改变的数组
changetimetotime=(ben-5 doe-1 john-1)
我需要满足的标准很少
我需要的bash代码
不需要的changetimetotime数量有3个,有时是1个值,但最大值是4个值。
固定数组只提供名称,changetimetotime也提供版本号。
一旦满足两个条件,阵列将变为
以下changetimetotime=(john-1 doe-1 ben-5)
我需要访问循环外的changetimetotime数组。
请帮忙。
答案 0 :(得分:1)
如果元素总是包含在使用稀疏数组的预定义集合中
fixed=(john doe mary ben)
# to fill an associative array from fixed array
# if supported (bash >4) otherwise use a decoding function
declare -A hash=()
for i in "${!fixed[@]}"; do hash[${fixed[i]}]=$i; done
changetimetotime=(ben-5 doe-1 john-1)
newchangetimetotime=()
for element in "${changetimetotime[@]}"; do
index=${hash[${element%%-*}]}
newchangetimetotime[index]=$element
done
echo "${newchangetimetotime[@]}"
# overwrite array reindexing keys
changetimetotime=("${newchangetimetotime[@]}")
否则,使用快速排序的一般情况
# an associative array to decode names to an int
declare -A hash=([john]="1" [doe]="2" [mary]="3" [ben]="4")
# or to fill from fixed array
# declare -A hash=()
# for i in "${!fixed[@]}"; do hash[${fixed[i]}]=$i; done
# function used to compare two elements
# exit status is success (0) if first is less or equal to second
is_ordered () {
# if string after name can contain many '-', % may be changed to %% to remove logest matched suffix
# extract names from elements
local k1=${1%-*} k2=${2%-*}
local v1=${hash[$k1]} v2=${hash[$k2]}
(($v1<=$v2))
}
# recursive quick sort
qsort () {
local l=() g=() p=$1
r=()
shift || return
for i; do
if is_ordered "$i" "$p"; then
l+=("$i")
else
g+=("$i")
fi
done
qsort "${g[@]}"
g=("${r[@]}")
qsort "${l[@]}"
l=("${r[@]}")
r=("${l[@]}" "$p" "${g[@]}")
}
qsort "${changetimetotime[@]}"
changetimetotime=("${r[@]}")