Chapter Contents

Previous

Next
COPYLIST

COPYLIST



Copies or merges the contents of an SCL list into an existing list or a new list

Category: List


Syntax
Details
Examples
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
See Also

Syntax

new-list-id=COPYLIST(list-id<,options>
<,target-list-id>);

new-list-id
is either the identifier of the new list to contain a copy of the contents of list-id, if target-list-id is not supplied, or target-list-id, if a target list is supplied.

Type: Numeric

list-id
is the identifier of the list to copy or merge into the target list. An invalid list-id produces an error condition.

Type: Numeric or List

options
specify whether list values are merged and control how sublists are copied or merged. You can use one or more of the following values, separated by spaces. Later keywords override previous keywords.

'NONRECURSIVELY'|'NO'|'N'
copies or merges only sublist identifiers as values for sublist items. (This is the default.)

'MERGE'|'M'
merges the contents of the source list-id into the target-list-id, replacing like-named existing items in the target list. You may combine this option with the recursive option. An error occurs if target-list-id is not supplied or is not a valid list identifier.

'RECURSIVELY'|'YES'|'Y'
copies or merges all items of sublists and of sublists of sublists, and so on.

Type: Numeric

target-list-id
is the identifier of the list into which the source list is copied or merged. If supplied, target-list-id is also returned. Otherwise, a new list is created and returned. New sublists are created with the same environment (local or global) as the target list.

An error condition results if the target list has attributes such as NOUPDATE and FIXEDLENGTH that prevent copying data into it.

Type: Numeric


Details

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.


Examples

Example 1: Copying a Single List

   /* 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'
         )[3]
      C=9.75
    )[5]
NREC=(  A=3.5
        B=(  x='ABC'
             y='XYZ'
           )[3]
        C=9.75
      )[7]
REC=(  A=3.5
       B=(  x='ABC'
            y='XYZ'
          )[11]
       C=9.75
     )[9]

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:   [5], [7], and [9] are the list identifiers that were assigned when this example was run and may be different each time the example is run.  [cautionend]

Example 2: Appending a List to Itself

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.

Example 3: Merging One List into Another List

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='?' )[7] )[5]
B before merge:(A=65 E=69 I=73 O=79 U=85
WHY=(NOT=0 )[11] )[9]
B after  merge :(A='A' E='E' I=73 O=79 U=85
WHY=(NOT='?' )[11] B='B' C='C'
D='D' F='F' )[9]

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.  [cautionend]

Example 4: Copying Multiple Instances of a List

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=(...)[13]
      R1=(...)[13]
      x=99
    )[13]
R2=(  a=1
      SELF=(  a=1
              SELF=(...)[13]
              R1=(...)[13]
              x=99
            )[13]
      R1=(...)[13]
      x=99
    )[15]
R3=(  a=1
      SELF=(...)[17]
      R1=(...)[17]
      x=99
    )[17]

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.  [cautionend]

Example 5: Merging Nonrecursively and Recursively

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);

See Also

DELLIST

GETLATTR

HASATTR

MAKELIST

MAKENLIST

PUTLIST

SETLATTR


Chapter Contents

Previous

Next

Top of Page

Copyright 1999 by SAS Institute Inc., Cary, NC, USA. All rights reserved.