help-bash
[Top][All Lists]
Advanced

[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



reply via email to

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