Skip to content

Commit

Permalink
add sort_list_named to sort an array variable in-place via nameref. (#27
Browse files Browse the repository at this point in the history
)

This avoids the requirement of a global "list" variable.
  • Loading branch information
jansorg committed Jun 18, 2024
1 parent f1b43f5 commit d1d256f
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 18 deletions.
48 changes: 30 additions & 18 deletions lib/sort.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,44 @@
sort_list() {
(($# != 2)) && return 1
typeset -i left=$1
((left < 0)) || (( 0 == ${#list[@]})) && return 2
((left < 0)) || ((0 == ${#list[@]})) && return 2
typeset -i right=$2
((right >= ${#list[@]})) && return 3
typeset -i i=$left; typeset -i j=$right
typeset -i mid; ((mid= (left+right) / 2))
typeset partition_item; partition_item="${list[$mid]}"
typeset -i i=$left
typeset -i j=$right
typeset -i mid
((mid = (left + right) / 2))
typeset partition_item
partition_item="${list[$mid]}"
typeset temp
while ((j > i)) ; do
item=${list[i]}
while [[ "${list[$i]}" < "$partition_item" ]] ; do
((i++))
done
while [[ "${list[$j]}" > "$partition_item" ]] ; do
((j--))
done
if ((i <= j)) ; then
temp="${list[$i]}"; list[$i]="${list[$j]}"; list[$j]="$temp"
((i++))
((j--))
fi
while ((j > i)); do
item=${list[i]}
while [[ "${list[$i]}" < "$partition_item" ]]; do
((i++))
done
while [[ "${list[$j]}" > "$partition_item" ]]; do
((j--))
done
if ((i <= j)); then
temp="${list[$i]}"
list[$i]="${list[$j]}"
list[$j]="$temp"
((i++))
((j--))
fi
done
((left < j)) && sort_list $left $j
((left < j)) && sort_list $left $j
((right > i)) && sort_list $i $right
return 0
}

# Sorts the array variable passed as 1st parameter from index $2 to index $3.
sort_list_named() {
(($# != 3)) && return 1
typeset -n list="$1"
sort_list "$2" "$3"
}

if [[ $0 == *sorting.sh ]] ; then
[[ -n $ZSH_VERSION ]] && setopt ksharrays
typeset -a list
Expand Down
12 changes: 12 additions & 0 deletions test/unit/test-sort.sh.in
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ test_sort()
assertNotEquals "0" "$?"
}

test_sort_named() {
local LC_ALL=C # for predictable sort order
typeset -a my_expected=(1 2 3 A B X b y z)

typeset -a my_data=(z b y 2 3 1 X A B)
sort_list_named my_data 0 ${#my_data[@]}-1
assertEquals "sort_list_named must complete successfully" 0 $?

for ((i=0; i < ${#my_expected[@]}; i++)); do
assertEquals "Expected sorted data at index $i." "${my_expected[i]}" "${my_data[i]}"
done
}

if [ '@abs_top_srcdir@' = '' ] ; then
echo "Something is wrong abs_top_srcdir is not set."
Expand Down

0 comments on commit d1d256f

Please sign in to comment.