|Example 1: Copying a Single List|
|Example 2: Appending a List to Itself|
|Example 3: Merging One List into Another List|
|Example 4: Copying Multiple Instances of a List|
|Example 5: Merging Nonrecursively and Recursively|
Type: Numeric or List
An error condition results if the target list has attributes such as NOUPDATE and FIXEDLENGTH that prevent copying data into it.
The copy operation appends items from the source list to the end of the target list, whereas the merge operation copies them into the target list, replacing existing named items.
If an SCL object is passed to COPYLIST as list-id, the resulting copy is not an SCL object. Although the new list contains all items from the original object, methods can not be called on this copy. The copied list is also treated as a regular list for comparisons (e.g., COMPARELIST).
If target-list-id is omitted, the function creates a new list in the same environment (L or G) as the list being copied and makes the new list the target-list-id. (For a description of list environments, see ENVLIST.) If target-list-id is supplied, its identifier is returned in new-list-id.
When a list is copied recursively, the items in all sublists are also copied, not just the sublist identifiers. However, even this duplication is avoided if it would result in an infinite recursion. When copying a list recursively, SCL does not perform an infinite recursive copy. For example, if a list contains itself, COPYLIST detects the circular structure and recreates the structure in the copy.
Merging occurs by item names. All items in the source list (and in its sublists, if merging is recursive) must have names. For each item, the name is used to find a matching name in the target list, as with NAMEDITEM(list-id name). If the same name appears multiple times in the source list, each item is merged independently. That is, the last occurrence of the name overwrites previous merged values and does not match with subsequent items in the target list. Thus, you should strive to keep item names unique in the source list in order to avoid wasted processing. If the corresponding item is not found in the target list, a new item is created.
In the merge operation, a list or sublist is merged only once, even if it appears multiple times. Also, a warning is printed for items that do not have names.
If an item in the source list has the NOWRITE attribute, then the corresponding item in the target list is deleted, unless it has the NODELETE attribute, in which case it is not merged. If a scalar item replaces a sublist item in a merge, the replaced list is not deleted because it may be used elsewhere. The SCL program must explicitly delete the old list.
All attributes of the list and its contents are preserved when a list is copied. The password is not copied so that you can modify the copy without knowing the password of the original list. The copy has no password. (See SETLATTR for a discussion of passwords for lists.)
COPYLIST ignores any invalid options and uses its defaults instead.
/* make B a local named list */ /* with 2 items named x, y */ b=makenlist('L','x','y'); b=setnitemc(b,'ABC','x'); b=setnitemc(b,'XYZ','y'); /* make A a local named list */ /* with 3 items named A, B, and C */ a=makenlist('L','A','B','C'); a=setnitemn(a,3.5,'A'); a=setniteml(a,b,'B'); a=setnitemn(a,9.75,'C'); call putlist(a,'A=',2); NREC=copylist(a,'N'); /* nonrecursive copy */ call putlist(NREC,'NREC=',2); REC=copylist(a,'Y'); /* recursive copy */ call putlist(REC,'REC=',2);
This program produces the following output:
A=( A=3.5 B=( x='ABC' y='XYZ' ) C=9.75 ) NREC=( A=3.5 B=( x='ABC' y='XYZ' ) C=9.75 ) REC=( A=3.5 B=( x='ABC' y='XYZ' ) C=9.75 )
The sublist named B in the outer list NREC is the same list as the sublist named B in the outer list named A, from which NREC was copied non-recursively. Both lists named B have the same list identifier (3), which means they are in fact the same list. However, the sublist named B in the outer list REC, which was copied recursively from list A, is a different list, although it has the same contents as the list named B from A. The sublist in the outer list REC has a list identifier of 11, not 3, which shows it is a different list.
Note: , , and  are the list
identifiers that were assigned when this example was run and may be different
each time the example is run.
Append the list MYLIST to itself. Both NEWLIST and MYLIST contain the list identifier for the copy of MYLIST.
mylist=makelist(); mylist=insertn(mylist,1,-1); mylist=insertn(mylist,2,-1); mylist=insertn(mylist,3,-1); newlist = copylist(mylist,'N',mylist);
NEWLIST contains the values 1, 2, 3, 1, 2, 3.
INIT: a = makenlist('L','A','B','C','D','E','F'); do i = 1 to listlen(a); a = setitemc(a, nameitem(a,i),i); end; c = insertc(makelist(),'?',-1,'NOT'); a = insertl(a, c,-1,'WHY'); b = makenlist('L','A','E','I','O','U'); do i = 1 to listlen(b); b = setitemn(b, rank(nameitem(b,i)),i); end; b = insertl(b, insertn(makelist(),0,-1,'NOT'),-1, 'WHY'); call putlist(a,'A before merge:'); call putlist(b,'B before merge:'); b = copylist(a,'yes merge',b); call putlist(b,'B after merge :'); return;
The result is
A before merge:(A='A' B='B' C='C' D='D' E='E' F='F' WHY=(NOT='?' ) ) B before merge:(A=65 E=69 I=73 O=79 U=85 WHY=(NOT=0 ) ) B after merge :(A='A' E='E' I=73 O=79 U=85 WHY=(NOT='?' ) B='B' C='C' D='D' F='F' )
The result list B contains items from A where the names intersect as well as original items from B for items that were not found in A. Because the sublist WHY was found in both, a recursive merge replaced 0 from the sublist of B with '?' from the sublist of A.
Note: 7, 5, 11, and 9 are the list identifiers that were assigned when this example
was run and may be different each time the example is run.
Copy a list, which contains a copy of itself, non-recursively and recursively. The outer list R1 contains two items, named SELF and R1, which are actually the same list as R1. When a non-recursive copy, R2, is made, the copy has items named SELF and R1 which are still the list R1. Only when R1 is copied recursively as R3 does the copy contain itself instead of R1.
/* Create the list L, fill it, and print R1. */ r1=makenlist('l','a','SELF','r1', 'x'); r1=setniteml(r1,r1,'SELF')); r1=setniteml(r1,r1,'r1')); r1=setnitemn(r1,1,'a')); r1=setnitemn(r1,99,'x')); call putlist(r1,'R1=',2)); /* Copy R1 nonrecursively into R2 and print R2 */ r2=copylist(r1,'n'); call putlist(r2,'R2=',2); /* Copy R1 recursively into R3 and print R3 */ r3=copylist(r1,'y'); call putlist(r3,'R3=',2);
The list R2, which was created with a nonrecursive copy operation, contains the list R1. Note that the structure of the list R3 is identical to that of R1: it contains two copies of itself, at items named SELF and R1, because these items are lists whose list identifier is the same as the list R3.
This program produces the following output:
R1=( a=1 SELF=(...) R1=(...) x=99 ) R2=( a=1 SELF=( a=1 SELF=(...) R1=(...) x=99 ) R1=(...) x=99 ) R3=( a=1 SELF=(...) R1=(...) x=99 )
Note: 13, 15, and 17 are the list identifiers
that were assigned when this example was run and may be different each time
the example is run.
Merge the contents of the list identified in SOURCEID into the list identified in TARGETID. The second call does a recursive merge.
targetid=copylist(sourceid,"MERGE",targetid); targetid=copylist(sourceid,"MERGE YES",targetid);
Top of Page
Copyright 1999 by SAS Institute Inc., Cary, NC, USA. All rights reserved.