[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Sorting an associative array by key fails
From: |
Kerin Millar |
Subject: |
Re: Sorting an associative array by key fails |
Date: |
Wed, 25 Aug 2021 22:29:26 +0100 |
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