:TITLE: Introduction to dict: Modifying Dict Data
;#
;# RCSID: $Header: /home/cvs/TclTutor3/lesson/Tcl_English/Tcl_English47.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:
One of the interesting features of the dict datastructure is that it is
a dynamic structure.  Unlike a C struct, or an SQL table, you can add
new fields or modify field names inside an application.

<P>
Changing values or adding new key/value pairs  can be done with the
<CODE>dict set</CODE> command described previously.

<P>
A new dict with modified values can be created using the <CODE>dict
replace</CODE> command.  The <CODE>dict replace</CODE> command returns
a new dict with the requested values modified.  The <CODE>dict replace</CODE>
command only modifies values, it will not modify keys.

<P>
Syntax: <CODE>dict replace <I>dictValue key val ?key val?</I> </CODE>
<UL>
<DL>
  <CODE><I><DT>dictValue</I></CODE>
  <DD>A dictionary value (ie. $dictName)

  <CODE><I><DT>key </I></CODE>
  <DD>The key for an element to be modified.

  <CODE><I><DT>val</I></CODE>
  <DD>The new value for an element.

</DL>
</UL>

<P>
The <CODE>dict update</CODE> command selects one or more values from a dictionary,
links a variable to that value (similar to an <CODE>upvar</CODE> command) and then
evaluates an optional script.  With the script, any modification of the variable
are reflected back into the dict.  After the script exits, the variables remain,
but are no longer linked to the dict value.

<P>
Syntax: <CODE>dict update <I>dictName key varName ?key varName? body </I> </CODE>
<DL>
  <CODE><I><DT>dictName </I> </CODE>
  <DD>The name of a dict variable

  <CODE><I><DT>key </I> </CODE>
  <DD>Key is a toplevel key in this dict.  
  <CODE><I><DT>varName ? </I> </CODE>
  The name of a variable to be linked to the value value associated with preceeding key.
  The script will be invoked once, after all the keys and variables have been linked.
  <P>
  If the key value is not in the
  dict, the associated <CODE>varName</CODE> will not exist.
  <P>  Any changes made to the contents of <CODE>varName</CODE> are reflected
  back into the dict.
  <DT><CODE><I> script</I> </CODE>
  <DD>A script to evaluate
</DL>

<P>
For example, this code creates a dict then uses the <CODE>dict update</CODE> 
command to modify the values.
<PRE><CODE>
# Define a simple dict: {a b c d}
set dd [dict create a b c d]
dict update dd a aVar c cVar {
    set aVar 2; 
    set cVar [string toupper $cVar]; 
}
# displays {a 2 c D}
set dd
</CODE></PRE>
:TEXT_END:

:LESSON_TEXT_START_LEVEL 1:
One of the interesting features of the dict datastructure is that it is
a dynamic structure.  Unlike a C struct, or an SQL table, you can add
new fields or modify field names inside an application.

<P>
Changing values or adding new key/value pairs  can be done with the
<CODE>dict set</CODE> command described previously.

<P>
A new dict with modified values can be created using the <CODE>dict
replace</CODE> command.  The <CODE>dict replace</CODE> command returns
a new dict with the requested values modified.  The <CODE>dict replace</CODE>
command only affects values, it will not modify keys.
<P>

The difference between using <CODE>dict set</CODE> and <CODE>dict replace</CODE>
is that <CODE>dict set</CODE> modifies a dictionary, while <CODE>dict replace</CODE>
returns a new dictionary which may have different values.

<P>
Syntax: <CODE>dict replace <I>dictValue key val ?key val?</I> </CODE>
<UL>
<DL>
  <CODE><I><DT>dictValue</I></CODE>
  <DD>A dictionary value (ie. $dictName)

  <CODE><I><DT>key </I></CODE>
  <DD>The key for an element to be modified.

  <CODE><I><DT>val</I></CODE>
  <DD>The new value for an element.

</DL>
</UL>
<P>
The code below shows how to use the <CODE>dict replace</CODE> command to create
a new dictionary with new values.

<PRE><CODE>
set dd [dict create a b c d]
set dd2 [dict replace $dd a 2 c D]
# displays {a 2 c D}
set dd2
# displays {a b c d}
set dd
</CODE></PRE>
<P>
The <CODE>dict update</CODE> command allows an application to select multiple
values from a dictionary at once and perhaps modify them.  This command
selects one or more values from a dictionary,
links a variable to that value (similar to an <CODE>upvar</CODE> command) and then
evaluates an optional script.  With the script, any modification of the variable
are reflected back into the dict.  After the script exits, the variables remain,
but are no longer linked to the dict value.

<P>
Syntax: <CODE>dict update <I>dictName key varName ?key varName? body </I> </CODE>
<DL>
  <CODE><I><DT>dictName </I> </CODE>
  <DD>The name of a dict variable

  <CODE><I><DT>key </I> </CODE>
  <DD>Key is a toplevel key in this dict.  
  <CODE><I><DT>varName ? </I> </CODE>
  The name of a variable to be linked to the value value associated with preceeding key.
  The script will be invoked once, after all the keys and variables have been linked.
  <P>
  If the key value is not in the
  dict, the associated <CODE>varName</CODE> will not exist.
  <P>  Any changes made to the contents of <CODE>varName</CODE> are reflected
  back into the dict.
  <DT><CODE><I> script</I> </CODE>
  <DD>A script to evaluate
</DL>

<P>
For example, this code creates a dict then uses the <CODE>dict update</CODE> 
command to modify the values.
<PRE><CODE>
# Define a simple dict: {a b c d}
set dd [dict create a b c d]
dict update dd a aVar c cVar {
    set aVar 2; 
    set cVar [string toupper $cVar]; 
}
# displays {a 2 c D}
set dd
</CODE></PRE>
:TEXT_END:

:LESSON_TEXT_START_LEVEL 2:
The Java or C++ class and the "C" structure are static datastructures
that are defined when the code is written.  The fields of these structures
can not be modified at runtime.
<P>
One of the interesting features of the dict datastructure is that it is
a dynamic structure.  Unlike a C struct, or an SQL table, you can add
new fields or modify field names inside an application.
<P>
This allows an application to create <I>sparse</I> data structures in
which only the keys that are needed are populated, or keys and values can
be added to a generic dictionary as the application discovers new keys
it and values it needs.

<P>
For example, an application might make a dictionary in which the primary
key is a Tcl command/subcommand pair and the
value is a syntax reminder.  If you later decided to add a new key/value
pair for the revision when a command was added it can be done with the 
<CODE>dict lappend </CODE> command.


<PRE><CODE>
  dict set cmds "string toupper" [dict create syntax "convert to uppercase"]
  dict set cmds "dict create" [dict create syntax "create a dictionary"]
  # Add new revision information
  dict set cmds "string toupper" revision 7.2
  dict set cmds "dict create" revision 8.5
</CODE></PRE>
<P>
Changing values or adding new key/value pairs  can be done with the
<CODE>dict set</CODE> command described previously.

<P>
A new dict with modified values can be created using the <CODE>dict
replace</CODE> command.  The <CODE>dict replace</CODE> command returns
a new dict with the requested values modified.  The <CODE>dict replace</CODE>
command only affects values, it will not modify keys.
<P>

The difference between using <CODE>dict set</CODE> and <CODE>dict replace</CODE>
is that <CODE>dict set</CODE> modifies a dictionary, while <CODE>dict replace</CODE>
returns a new dictionary which may have different values.

<P>
Syntax: <CODE>dict replace <I>dictValue key val ?key val?</I> </CODE>
<UL>
<DL>
  <CODE><I><DT>dictValue</I></CODE>
  <DD>A dictionary value (ie. $dictName)

  <CODE><I><DT>key </I></CODE>
  <DD>The key for an element to be modified.

  <CODE><I><DT>val</I></CODE>
  <DD>The new value for an element.

</DL>
</UL>
<P>
The code below shows how to use the <CODE>dict replace</CODE> command to create
a new dictionary with new values.

<PRE><CODE>
set dd [dict create a b c d]
set dd2 [dict replace $dd a 2 c D]
# displays {a 2 c D}
set dd2
# displays {a b c d}
set dd
</CODE></PRE>
<P>
The <CODE>dict update</CODE> command allows an application to select multiple
values from a dictionary at once and perhaps modify them.  This command
selects one or more values from a dictionary,
links a variable to that value (similar to an <CODE>upvar</CODE> command) and then
evaluates an optional script.  With the script, any modification of the variable
are reflected back into the dict.  After the script exits, the variables remain,
but are no longer linked to the dict value.

<P>
Syntax: <CODE>dict update <I>dictName key varName ?key varName? body </I> </CODE>
<DL>
  <CODE><I><DT>dictName </I> </CODE>
  <DD>The name of a dict variable

  <CODE><I><DT>key </I> </CODE>
  <DD>Key is a toplevel key in this dict.  
  <CODE><I><DT>varName ? </I> </CODE>
  The name of a variable to be linked to the value value associated with preceeding key.
  The script will be invoked once, after all the keys and variables have been linked.
  <P>
  If the key value is not in the
  dict, the associated <CODE>varName</CODE> will not exist.
  <P>  Any changes made to the contents of <CODE>varName</CODE> are reflected
  back into the dict.
  <DT><CODE><I> script</I> </CODE>
  <DD>A script to evaluate
</DL>

<P>
For example, this code creates a dict then uses the <CODE>dict update</CODE> 
command to modify the values.
<PRE><CODE>
# Define a simple dict: {a b c d}
set dd [dict create a b c d]
dict update dd a aVar c cVar {
    set aVar 2; 
    set cVar [string toupper $cVar]; 
}
# displays {a 2 c D}
set dd
</CODE></PRE>
:TEXT_END:

:CODE_START:
set t1 [dict create a b c d]
puts "Start Dict is: $t1"

set t2 [dict replace $t1 a A]
puts "After Replace: $t2"

set t3 [dict replace $t1 a A b B c C]
puts "After Replace with unmatched key b: $t3"

dict update t1 a aa c cc {
  if {[info exists aa]} {set aa B}
  if {[info exists cc]} {set cc D}
}

puts "t1 after update: $t1"

set t1 {a b c d e f}
dict with t1  {
  puts "A: $a C: $c E: $e"
  puts "Does value exist? [info exists b] (0 = No)"
  set a AA
  set c CC
  set e EE
}

set t1 [dict create a {b c} d {e {f g}}]

# Look at first element:
puts "Contents of dict value for key=a: [dict with t1 a {puts $b}]"

puts "Contents of dict value for key=d: [dict with t1 d {puts $e}]"

puts "Contents of dict value for key=d/e: [dict with t1 d e {puts $f}]"

:TEXT_END:

	 
