help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Sorting an associative array by key fails


From: hancooper
Subject: Sorting an associative array by key fails
Date: Wed, 25 Aug 2021 22:13:28 +0000

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Wednesday, August 25, 2021 9:29 PM, Kerin Millar <kfm@plushkava.net> wrote:

> On Wed, 25 Aug 2021 19:37:47 +0000
> hancooper hancooper@protonmail.com wrote:
>
> > ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
> > On Wednesday, August 25, 2021 5:56 PM, Kerin Millar kfm@plushkava.net wrote:
> >
> > > On Wed, 25 Aug 2021 17:30:08 +0000
> > > hancooper via help-bash@gnu.org wrote:
> > >
> > > > I am populating an associative array, which I want to sort later by key 
> > > > for display purposes.
> > > > The sort will fail with the following code, because the sort gives
> > > > 1-0
> > > > 1-12
> > > > 1-15
> > > > 1-18
> > > > 1-21
> > > > 1-24
> > > > 1-27
> > > > 1-3
> > > > 1-30
> > > > 1-33
> > > > 1-36
> > > > 1-39
> > > > 1-42
> > > > 1-45
> > > > 1-48
> > > > 1-51
> > > > 1-54
> > > > 1-57
> > > > 1-6
> > > > 1-9
> > > > Somehow I need a function that I can pass a numeric value and returns 
> > > > me a string with
> > > > a tho appropriate nember of zeroes appended at the beginning (e.g. to 
> > > > get 1-00, 1-01, 1.02, ... ).
> > > > Here is the code.
> > > > local i
> > > > declare -A asc
> > > > for (( i = 0; i < ndlc; i++ )); do
> > > > k=$(( (i % nproc) + 1 ))
> > > > elm=${dlc[$i]} ; elm=${elm#*$'\t'} # remove size entry
> > > > asc[$k-$i]="$elm" # set dir name
> > > > (( vb >=3 )) && echo "asc[$k-$i]=dlc[$i]"
> > > > done
> > >
> > > Though non-portable: done | sort -V.
> >
> > To sort an array of keys, would one prefer
> > $( echo "${!_asc[@]}" | tr ' ' '\n' | sort -V )
> > over
> > $( echo "${!_asc[*]}" | tr ' ' '\n' | sort -V )
> > Or is there a more convenient way to do this?
>
> Well, it could certainly be implemented more reliably. The following approach 
> continues to use $'\n' as a delimiter, while dispensing with the issues that 
> may potentially arise from word splitting and pathname expansion.
>
> mapfile -t sorted_keys < <(printf '%s\n' "${!keys[@]}" | sort -V)
>
> Given that you have sort -z at your disposal, you may use NUL as a delimiter 
> instead.
>
> mapfile -td '' sorted_keys < <(printf '%s\0' "${!keys[@]}" | sort -zV)
>
> Granted, the way in which you are composing your array keys means that any of 
> the approaches under discussion would do. Still, the latter approach has the 
> advantage of using a known-safe delimiter, besides conveniently storing the 
> key list in an array variable.
>
> Kerin Millar

Quite right.  Thank you so very much.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]