Friday, June 16, 2017

CONTAINERS AND METHODS :MICROSOFT DYNAMICS 365:DYNAMICS AX 2012 X++ :CONPEEK:CONFIND

CONTAINERS AND METHODS

In X++, container is one of the primitive types, or value types. container is not a class. A container contains an ordered sequence of primitive values or other containers.
A container can be stored in the database. container is one of the column types that you can select when you use the Application Object Tree (AOT) to add a column to a table.
A container slightly resembles an array, or collections such as the List or Stack classes. However, you can never change the size or content of a container after the container is created. X++ statements that appear to modify a container are internally building a new container and copying values as necessary. Even an assignment of a container to another container variable creates a new copy of the container. All of this has performance implications.
In the X++ functions that provide access to a container (such as conPeek), the container is 1 based not 0 based. Indexing is 1 based for arrays, and for everything else in X++.

Syntax

This section describes the X++ syntax you must use to handle a container.

Operators

The following table shows the X++ operators that can be applied to the container type.
Operator
Example
Description
=
myContainer2 = [2, "apple"];
myContainer33 = [33, "grape"];
myContainer2 = myContainer33;
The example initializes myContainer2 and myContainer33.
Next, it makes a copy of myContainer33, and assigns the copy to myContainer2.
The container that myContainer2 had been holding is no longer available (and cannot be recovered).
+=
myContainer33 += [34, "banana"];
Builds a new container and assigns it to myContainer33. The new container is populated by appending the assigned elements to those in the original myContainer33.
The original myContainer33 is no longer available.

Statements

The following table displays the syntax of statements that handle a container.
Action
Example
Declare a container
container cr3;
Assign a literal container to a container variable
cr3 = [22, "blue"];
Declare and assign a container
container cr2 = [1, "blue", true];
Mimic container modification (implicitly creates a copy)
cr3 += [16, strMyColorString];
cr3 = conIns(cr3, 1, 3.14);
cr3 = conPoke(cr3, 2, "violet");
Assignment of a container (implicitly creates a copy)
cr2 = cr3;
Read a value from the container
myStr = conPeek(cr2, 1);
One statement that does multiple assignments from a container
str myStr;
int myInt;
container cr4 = ["Hello", 22, 20\07\1988];
;
[myStr, myInt] = cr4; // "Hello", 22

Functions

There are several intrinsic X++ functions for handling a container, such as conIns and conPeek. For more information about the intrinsic X++ functions for handling a container, see Functions for Manipulating Container Content.
The Global Class has static methods for handling containers. Among those methods are the following:
·         con2ArraySource
·         con2Buf
·         con2List
·         con2Str
·         containerFromXmlNode
·         conView
·         str2Con

Container is a Value Type, not a Reference Type

Any class is a reference type. But container is a value type. Variables declared as value types are never null. Even the X++ function conNull returns a container. A variable declared as a container is automatically initialized to an empty container (a container that contains no values).
There are two code samples in the following table. In only the List class sample do variable2 and variable33 refer to the same thing (the same List object). In the container sample, the two variables hold different containers.
container
List class
X++
static void JobC(Args _args)
{
    container variable2
        ,variable33;
    ;
    variable2 += [98];
    variable33 = variable2;
    variable2 += [97];
}
X++
static void JobL(Args _args)
{
    List variable2
        ,variable33;
    ;
    variable2 = new List
        (Type::Integer);
    variable2.addEnd(98);
    variable33 = variable2;
    variable2.addEnd(97);
}

Containers are Immutable

Some X++ statements with containers might appear like they modify a container, but inside the system this never occurs. Instead, the data from the original container is combined with data from the command to build a new container.
You create a new container every time that you call any of the following functions:
·         conDel
·         conIns
·         conPoke
The following statements all create a new container:
·         myContainer = [1];
·         myContainer += [2];
·         myContainer4 = myContainer5;

Automatic Type Conversions by Anytype

The X++ function conPeek returns an anytype type. The flexibility of anytype makes container a good way to store values of different types together. This makes it easier to read the values from a container when you do not know what type each value is. An anytype can be assigned to any X++ value type, as long as the value can be converted.
The automatic conversion by anytype also applies to the special syntax for making multiple assignments from a container in one statement. This is shown in the following code example, which assigns a str to an int, and an int to a str.
X++
static void JobContainerMultiAssignmentUsesAnytype(Args _args)
{
    container con2;
    int int4;
    str str7;
 
    con2 = ["11", 222];
    [int4, str7] = con2;
    info(strfmt("int4==11==(%1), str7==222==(%2)"
        , int4, str7));
}
/***  Pasted from output:
Message (10:36:22 am)
int4==11==(11), str7==222==(222)
***/
Your code is easier to read when it avoids implicit data type conversions. Assign values from a container to the same data type that was used to put the value into the container.
You must not assign a container to an anytype, because the system is unable to determine the correct conversions in some cases. In these cases, unexpected behavior or errors might occur.

Performance of Containers

A container is best suited for processes that do not involve excessive modification to the size or contents of the container. When a container undergoes excessive additions of data, overall system performance can be decreased by the need to repeatedly copy container data and allocate new space.

+= is Faster Than conIns

When you want to build a new container by appending new data, you can use either the += operator or the conIns function. The += operator is the faster alternative. Use the conIns function only when you want to add new data before the last index of the original data.

Comparing container to other Options

The container type slightly resembles other constructs, such as arrays and collection classes like List and Stack. The next sections compare and contrast container with these other options.

Differences Between container and List

An instance of the List class is mutable. A List object first allocates more space than its data consumes. As data is added the space is filled. This is more efficient than allocating more space every time that an element is added. Updating a List performs faster than similar operations on a container.
When you construct a List object, you determine the one type of data that the List object can store. This restriction is less flexible than for a container. However, you can choose to store objects in a List, whereas a container can only store value types.
Note
For more information about X++ data types, see Data Types in X++.

Differences Between container and an Array

An array can hold only items of its declared type.

You can allocate memory space for an array and fill that space with values later, such as in a loop. This is efficient and performs well.

conDel Function

Removes the specified number of elements from a container.
 
container conDel(container container, int start, int number)

Parameters

Parameter
Description
container
The container from which to remove elements.
start
The one-based position at which to start removing elements.
number
The number of elements to delete.

Return Value

A new container without the removed elements.

Example

X++
static void conDelExample(Args _args)
{
    container c = ["Hello world", 1, 3.14];
    ;
    // Deletes the first two items from the container.
    c = conDel(c, 1, 2);
}

conFind Function

Locates the first occurrence of an element or a sequence of elements in a container.
 
int conFind (container container, anytype element,... )  

Parameters

Parameter
Description
container
The container to search.
element
One or more elements to search for, separated by commas.

Remarks

If several elements are specified in the sequence, they must be separated by commas and specified in the correct sequence. The elements can be of any data type.

Return Value

Returns 0 if the item was not found; otherwise, the sequence number of the item.

Example

X++
static void conFindExample(Args _args)
{
    container c = ["item1", "item2", "item3"];
    int i;
    int j;
    ;
 
    i = conFind(c, "item2");
    j = conFind(c, "item4");
    print "Position of 'item2' in container is " + int2Str(i);
    print "Position of 'item4' in container is " + int2Str(j);
    pause;
}

conIns Function

Inserts one or more elements into a container.
 
container conIns (
        container container, 
    int start, 
    anytype element,
        ... )

Parameters

Parameter
Description
container
The container into which to insert elements.
start
The position at which to insert elements.
element
One or more elements to insert, separated by commas.

Return Value

The new container with the inserted elements.

Remarks

The first element of the container is specified by the number 1. To insert after the n element, the start parameter should be n+1.
You can also use the += operator to add values of any type into a container. For example, to create a container that contains the squared values of the first 10 loop iterations:
X++
int i;
container c;
;
 
for (i = 1; i < = 10; i++)
{
    c += i*i;
} 

Example

X++
static void conInsExample(Args _arg)
{
    container c;
    int i;
    ;
 
    c = conIns(c,1,"item1");  
    c = conIns(c,2,"item2");
    for (i = 1 ; i <= conLen(c) ; i++)  
    {
    // Prints the content of a container.
        print conPeek(c, i);
    }
    pause;
 
}

conLen Function

Retrieves the number of elements in a container.
 
int conLen(container container)

Parameters

Parameter
Description
container
The container in which to count the number of elements.

Return Value

The number of elements in the container.

Example

X++
static void conLenExample(Args _arg)
{
    container c;
    int i;
    ;
 
    c = conins(["item1", "item2"], 1);  
    for (i = 1 ; i <= conLen(c) ; i++)
    {
        print conPeek(c, i);
     }
    pause;
}

conPoke Function

Modifies a container by replacing one or more of the existing elements.
 
container conPoke(
    container container,
    int start,
    anytype element,
    ...)

Parameters

Parameter
Description
container
The container to modify.
start
The position of the first element to replace.
element
One or more elements to replace, separated by commas.

Return Value

The new container with the new elements.

Remarks

The first element of the container is specified by the number 1.

Example

X++
static void conPokeExample(Args _arg)
{
    container c1 = ["item1", "item2", "item3"];
    container c2;
    int i;
 
    void conPrint(container c)
    {
        for (i = 1 ; i <= conLen(c) ; i++)
        {
            print conPeek(c, i);
        }
    }
    ;
    conPrint(c1);
    c2 = conPoke(c1, 2, "PokedItem");
    print "";
    conPrint(c2);
    pause;
}

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...