Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

lsearch with string map foreach element?

87 views
Skip to first unread message

Juge

unread,
Mar 10, 2017, 1:54:35 AM3/10/17
to
I am trying to get a list of keys with array names.
My keys have a format p1w1 p1w2 p2w1 p2w22
actually p stands for page and the integer after the letter p is a number of page
w stands for window and is a index for window.

Now I would like to search for all of the window definitions for let's say page 2
I would do:
lsearch -all [array names myArr] p2w

The answer would be:
p2w1 p2w22

However, in the end I want to have my list sorted based on the window id which means that in ideal case I would like to have a list of window ids alone:
2 and 22
this I could sort with lsort.

Is there a way of putting this in a one liner - I imagined that using regexp and inline option I might get there, but so far I got nowhere.

Of course I can use foreach and make a new list but I assume there might be a more elegant way?

Dave

unread,
Mar 10, 2017, 2:27:08 AM3/10/17
to
Maybe one of these:

set keys [array names myArr]

puts "#1: [lsort -unique [lmap v $keys { string range $v 3 end }]]"

puts "#2: [lsort -unique [regsub -all {p\d+w} $keys {}]]"



--
computerjock AT mail DOT com

Rich

unread,
Mar 10, 2017, 8:13:34 AM3/10/17
to
lsort offers an additonal option to call a custom list element
comparison command. For this use, you could use lsort with a
"-command" directed to a custom proc (or a lambda if you don't want to
create a proc) to sort on the trailing portion of each key.

jda...@gmail.com

unread,
Mar 10, 2017, 11:41:16 PM3/10/17
to
[array names] allows -glob -exact and -regexp searches as part of the command
[lsort] has -dictionary sort, so p2w13 comes after p2w3

for example:
lsort -dictionary [array names myArr p2w*]
gives a sorted list of all windows for page 2 in myArr

the sorting will not be strictly in window order if mutiple pages are allowed in the [array names] result

Donald Arseneau

unread,
Mar 11, 2017, 3:29:34 AM3/11/17
to
Juge <jyrki.m...@gmail.com> writes:

> lsearch -all [array names myArr] p2w
>
> The answer would be:
> p2w1 p2w22
>
> However, in the end I want to have my list sorted based on the window id which means that in ideal case I would like to have a list of window ids alone:
> 2 and 22
> this I could sort with lsort.

> Is there a way of putting this in a one liner


lsearch -all -inline -sorted -dictionary -glob [array names myArr] "p2w*"

(The -glob style is important if you want to select window, like "p*w1"
and not get w11.)

Hmmmmmm..... we seem to have a bug here...

% array set myArr {p1w1 . p1w5 . p2w1 . p2w8 . p2w11 . p2w12 . p11w1 . p12w55 .}
% lsearch -all -inline -sorted -dictionary -glob [array names myArr] "p2w*"
p2w12 p2w8 p2w1 p2w11
% lsort -dictionary [lsearch -all -inline -sorted -dictionary -glob [array names myArr] "p2w*"]
p2w1 p2w8 p2w11 p2w12
% info pat
8.6.1

I will have to get 8.6.6 installed and test there.


--
Donald Arseneau as...@triumf.ca

Donald Arseneau

unread,
Mar 11, 2017, 3:31:10 AM3/11/17
to
Donald Arseneau <as...@triumf.ca> writes:

Utter nonsense
> % lsearch -all -inline -sorted -dictionary -glob [array names myArr] "p2w*"

please ignore.

--
Donald Arseneau as...@triumf.ca

Donald Arseneau

unread,
Mar 11, 2017, 3:36:12 AM3/11/17
to
Donald Arseneau <as...@triumf.ca> writes:

Utter nonsense
> % lsearch -all -inline -sorted -dictionary -glob [array names myArr] "p2w*"
Please ignore.


Todays' motto is type fast, send fast, think slow.... Just slow enough
to send first.


--
Donald Arseneau as...@triumf.ca

matthe...@gmail.com

unread,
Mar 22, 2017, 10:22:34 AM3/22/17
to
How about

proc get_windows {arr_str page} {
array set arr $arr_str
return [lmap idx [array names arr p${page}w*] {lindex [split $idx w] end}]
}


% array set myArr {p1w1 {} p1w2 {} p2w1 {} p2w22 {}}
% get_windows [array get myArr] 1
1 2
% get_windows [array get myArr] 2
22 1

Donal K. Fellows

unread,
Mar 25, 2017, 3:08:09 PM3/25/17
to
On 10/03/2017 06:54, Juge wrote:
> Is there a way of putting this in a one liner - I imagined that using
> regexp and inline option I might get there, but so far I got
> nowhere.

The best thing is to use the optional filtering argument to [array
names], which takes a standard glob pattern, and then [lsort
-dictionary] to order the result (which is an ordering designed to “do
the right thing” in a lot of common cases; it sorts digit sequences as
numbers and the rest according to standard letter rules). With just two
commands required to do all the work, making a one-liner is simple.

set page 2
set keys [lsort -dictionary [array names myArr p${page}w*]]

Donal.
--
Donal Fellows — Tcl user, Tcl maintainer, TIP editor.
0 new messages