From: Donald Arseneau on
On Apr 11, 10:33 pm, Glenn Jackman <gle...(a)ncf.ca> wrote:
> At 2010-04-11 11:52PM, "tom.rmadilo" wrote:
>
> >  On Apr 11, 8:23 pm, Keith <kilowattra...(a)use-reply-to.invalid> wrote:
> [...]
> > >  I want to sort the values in the arrays.
>
> > > $foo(arr,1) = "C wordone"
> > > $foo(arr,2) = "A wordone"
>
> >  I assume once you sort, you end up with a list. So ditch the array and
> >  use a list to begin with like this:
>
> >  % set mylist {{arr,1 "C wordone"} {arr,2 "A wordone"}}
>
> Well, you don't have to ditch the array:
>
>     set mylist [list]
>     foreach {key value} [array get foo] {
>         lappend mylist [list $key $value]
>     }
>
> >  then use [lsort]
>
> >  % lsort -index 1 $mylist
> >  {arr,2 "A wordone"} {arr,1 "C wordone"}
>
> If you have Tcl 8.6, you can achieve the same kind of thing quicker:
>
>     array set foo {arr,1 "C wordone" arr,2 "A wordone"}
>     lsort -stride 2 -index 1 [array get foo]
>     # ==> arr,2 {A wordone} arr,1 {C wordone}
>
> --
> Glenn Jackman
>     Write a wise saying and your name will live forever. -- Anonymous

From: Donald Arseneau on
On Apr 11, 10:33 pm, Glenn Jackman <gle...(a)ncf.ca> wrote:
>     array set foo {arr,1 "C wordone" arr,2 "A wordone"}
>     lsort -stride 2 -index 1 [array get foo]
>     # ==> arr,2 {A wordone} arr,1 {C wordone}

I don't think that is useful, especially if it is converted back to an
array.
I imagine Keith wants

# ==> arr,1 {A wordone} arr,2 {C wordone}

Since the list of names emitted by [array get] is unsorted, any
sorting
work is really cumbersome, and indicates the choice of data structure
was poor. The data should be in nested lists rather than in a pseudo-
multidemensional array.

Working with the array as specified entails sorting both the names
and the values separately, and is made more cumbersome by the
lack of an [array values] command. (Even [dict values] doesn't
allow selecting a subset of keys directly, but I will use dict
anyway.)

set foodict [array get foo "arr,*"]
foreach name [lsort -dictionary [dict keys $foodict]] \
value [lsort -however [dict values $foodict]] {
set foo($name) $value
}

Keith never said *how* the values are to be sorted (strings, numbers,
whatever) so I used "-however" for the sort order.

Donald
From: Glenn Jackman on
At 2010-04-12 04:05AM, "Donald Arseneau" wrote:
> On Apr 11, 10:33�pm, Glenn Jackman <gle...(a)ncf.ca> wrote:
> > � � array set foo {arr,1 "C wordone" arr,2 "A wordone"}
> > � � lsort -stride 2 -index 1 [array get foo]
> > � � # ==> arr,2 {A wordone} arr,1 {C wordone}
>
> I don't think that is useful, especially if it is converted back to an
> array.
> I imagine Keith wants
>
> # ==> arr,1 {A wordone} arr,2 {C wordone}

Well, we're all imagining what Keith wants ("I want to sort the values
in the arrays.")

--
Glenn Jackman
Write a wise saying and your name will live forever. -- Anonymous
From: tom.rmadilo on
On Apr 12, 7:14 am, Glenn Jackman <gle...(a)ncf.ca> wrote:

> Well, we're all imagining what Keith wants ("I want to sort the values
> in the arrays.")

In Tcl you don't sort arrays, you sort lists. Tcl Arrays do not have
an ordered representation, they just have an interface.

Another problem with sorting on values is that the values could be the
same, so the actual order of the un-ordered values will affect result
of the sort. If the data is stored as an array before being dumped
into a list, you will not be able to predict the results of the sort.

Predictable results can be produced using two [lsort]s:

% set mylist {{a b} {b b} {e b} {d b} {h b} {aa b}}

% set sorted [lsort -index 0 [lsort -index 1 $mylist]]
{a b} {aa b} {b b} {d b} {e b} {h b}

This doesn't work:

% set not-sorted [lsort -index 1 $mylist]
{a b} {b b} {e b} {d b} {h b} {aa b}

This works:

% set still-sorted [lsort -index 0 [lsort -index 1 [lreverse
$mylist]]]
{a b} {aa b} {b b} {d b} {e b} {h b}


From: MSEdit on

Is there something wrong with

foreach ent [lsort -dictionary [array names foo]] {
# Process the entries in order
$foo($ent)
}

or am I missing something ?
this is what I always use.

Martyn