基于预定义列表排序

时间:2017-10-26 07:56:14

标签: arrays bash sed

如何根据我在Bash中预定义的列表对数组顺序进行排序。

我预定义的列表

fixed=(john doe mary ben)

我希望它改变的数组

changetimetotime=(ben-5 doe-1 john-1)

我需要满足的标准很少

我需要的bash代码

  1. 不需要的changetimetotime数量有3个,有时是1个值,但最大值是4个值。

  2. 固定数组只提供名称,changetimetotime也提供版本号。

  3. 一旦满足两个条件,阵列将变为

    以下
    changetimetotime=(john-1 doe-1 ben-5) 
    

    我需要访问循环外的changetimetotime数组。

    请帮忙。

1 个答案:

答案 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[@]}")