:TITLE: More list commands - lsearch, lsort, lrange
;#
;# RCSID: $Header: /home/cvs/TclTutor3/lesson/Tcl_English/Tcl_English16.lsn,v 1.2 2010/12/22 15:53:19 clif Exp $
;# Copyright (c) 1995 Clif Flynt
;# 9300 Fleming Rd.
;# Dexter, MI  48130
;# clif@cflynt.com
;# See file "NOTICE" for licensing terms.
;#
:LESSON_TEXT_START_LEVEL 0:
Lists can be searched with the <CODE>lsearch</CODE> command,
sorted with the <CODE>lsort</CODE> command, and a range of list entries can be
extracted with the <CODE>lrange</CODE> command.
<DL>
<B><DT>lsearch</B> <I>list pattern</I>
<DD> searches <I>list</I> for an entry that matches <I>pattern</I>, and returns
the index for the first match, or a -1 if there is no match.
<B><DT>lsort</B> -option <I>list</I>
<DD> sorts <I>list</I> and returns a new list in the sorted order.  By default,
it sorts the list into ASCII order (Numbers first, then upper case, then lowercase).
<P>You can change the order by using an option:
<BR> -dictionary : Dictionary order (2 comes before 10, a comes before B, etc)
<BR> -decreasing : Largest items first

<B><DT>lrange</B> <I>list first last</I>
<DD> returns a list composed of the <I>first</I> through <I>last</I> entries
in the list.  If <I>first</I> is less than or equal to 0, it is treated as the
first list element.  If <I>last</I> is <B>end</B> or a value greater than the
number of elements in the list, it is treated as the end.  If <I>first</I> is
greater than <I>last</I> then an empty list is returned.
</DL>
By default, lsearch uses the <B>globbing</B> method of finding a match. 
<B>Globbing</B> is the wildcarding technique that the shell uses.  
:TEXT_END:

:LESSON_TEXT_START_LEVEL 1:
Lists can be searched with the <CODE>lsearch</CODE> command,
sorted with the <CODE>lsort</CODE> command, and a range of list entries can be
extracted with the <CODE>lrange</CODE> command.
<DL>
<B><DT>lsearch</B> <I>list pattern</I>
<DD> searches <I>list</I> for an entry that matches <I>pattern</I>, and returns
the index for the first match, or a -1 if there is no match.
<B><DT>lsort</B> -option <I>list</I>
<DD> sorts <I>list</I> and returns a new list in the sorted order.  By default,
it sorts the list into ASCII order (Numbers first, then upper case, then lowercase).
<P>You can change the order by using an option:
<BR> -dictionary : Dictionary order (2 comes before 10, a comes before B, etc)
<BR> -decreasing : Largest items first

<B><DT>lrange</B> <I>list first last</I>
<DD> returns a list composed of the <I>first</I> through <I>last</I> entries
in the list.  If <I>first</I> is less than or equal to 0, it is treated as the
first list element.  If <I>last</I> is <B>end</B> or a value greater than the
number of elements in the list, it is treated as the end.  If <I>first</I> is
greater than <I>last</I> then an empty list is returned.
</DL>
<P>
By default, lsearch uses the <B>globbing</B> method of finding a match. 
<B>Globbing</B> is the wildcarding technique that the shell uses.  
<P>
<B>globbing</B> wildcards are:
<DL>
<B><DT>*</B><DD> Matches any quantity of any character
<B><DT>?</B><DD> Matches one occurrence of any character
<B><DT>\X</B><DD> The backslash escapes a special character in globbing
just the way it does in Tcl substitutions.  Using the backslash lets you use 
glob to match a <B>*</B> or <B>?</B>.  
<B><DT>[...]</B><DD> Matches one occurrence of any character within the brackets.
A range of characters can be matched by using a range between the brackets.
For example, [a-z] will match any lower case letter.
</DL>
:TEXT_END:

:LESSON_TEXT_START_LEVEL 2:
There are several other operations which can be performed on a list.
Lists can be 
<UL>
<LI>searched with the <CODE>lsearch</CODE> command,
<LI>sorted with the <CODE>lsort</CODE> command,
<LI> a range of list entries can be extracted with the <CODE>lrange</CODE> command.
</UL>
<DL>
<B><DT>lsearch</B> <I>list pattern</I>
<DD> searches <I>list</I> for an entry that matches <I>pattern</I>, and returns
the index for the first match, or a -1 if there is no match.
<B><DT>lsort</B> -option <I>list</I>
<DD> sorts <I>list</I> and returns a new list in the sorted order.  By default,
it sorts the list into ASCII order (Numbers first, then upper case, then lowercase).
<P>You can change the order by using an option:
<BR> -dictionary : Dictionary order (2 comes before 10, a comes before B, etc)
<BR> -decreasing : Largest items first
<B><DT>lrange</B> <I>list first last</I>
<DD> returns a list composed of the <I>first</I> through <I>last</I> entries
in the list.  If <I>first</I> is less than or equal to 0, it is treated as the
first list element.  If <I>last</I> is <B>end</B> or a value greater than the
number of elements in the list, it is treated as the end.  If <I>first</I> is
greater than <I>last</I> then an empty list is returned.
</DL>
<P>
By default, lsearch uses the <B>globbing</B> method of finding a match. 
<B>Globbing</B> is the wildcarding technique that the shell uses.  The
<B>globbing</B> wildcards are:
<DL>
<B><DT>*</B><DD> Matches any quantity of any character
<P> <CODE>lsearch $list a*</CODE> would return the index of the first 
listitem that started with the letter 'a', regardless of what followed.
<B><DT>?</B><DD> Matches one occurrence of any character
<P> <CODE>lsearch $list a?</CODE> would return the index of the first 
listitem that started with the letter 'a', and had only one character 
after the a.
<B><DT>\X</B><DD> The backslash escapes a special character in globbing
just the way it does in Tcl substitutions.  Using the backslash lets you use 
glob to match a <B>*</B> or <B>?</B>.  
<P> <CODE>lsearch $list a\*</CODE> would return the index of the first listitem that 
started with the letter 'a', and had an asterisk after the 'a'.
<B><DT>[...]</B><DD> Matches one occurrence of any character within the brackets.
A range of characters can be matched by using a range between the brackets.
For example, [a-z] will match any lower case letter.
<P> <CODE>lsearch $list [a-e]*</CODE> would return the index of the 
first listitem that started with a letter between 'a' and 'e'.
</DL>
<P>
Run the example code.  Try removing the * in the lsearch commands, and see
how that affects the output.
:TEXT_END:

:CODE_START:

set list [list {Washington 1789} {Adams 1797} {Jefferson 1801} \
               {Madison 1809} {Monroe 1817} {Adams 1825} ]

set x [lsearch $list Washington*];
set y [lsearch $list Madison*];
incr x; incr y -1;		;# Set range to be not-inclusive

set subsetlist [lrange $list $x $y]

puts "The following presidents served between Washington and Madison"
foreach item $subsetlist {
  puts "Starting in [lindex $item 1]: President [lindex $item 0] "
  }


set x [lsearch $list Madison*]

set srtlist [lsort $list];
set y [lsearch $srtlist Madison*];

puts "\n$x Presidents came before Madison chronologically"
puts "$y Presidents came before Madison alphabetically"

:TEXT_END:

