The IDL_Variable class contains static methods that are available for all IDL variables except objects and structures.

## Attributes

All IDL variables have special attributes that return information about the variable:

var.dim | An array giving the dimensions (0 for scalars). |

var.length | The number of elements in the variable. |

var.ndim | An integer giving the number of dimensions (0 for scalars). |

var.tname | A string giving the raw IDL type name. For structures this returns "STRUCT", while for objects this returns "OBJREF". |

var.typecode | An integer giving the IDL type code. |

var.typename |
A string giving the IDL type name. For structures and objects this returns the actual structure or class name. |

See Variable Attributes for more details.

## Superclasses

None

### IDL_Variable

- Compare: Compare to another variable and return –1, 0, or 1 for each value.
- Convert: Convert the variable to a different data type.
- Diff: Returns the unique elements that have been added to or removed from a variable.
- Dup: Duplicate a scalar value into an array.
- Equals: Tests whether two variables are equal.
- Filter: Returns only data values that successfully pass through a user-defined filter or Lambda function.
- Finite: Returns only the finite values within an array.
- FromBits: Converts the variable from an array of bits.
- Hashcode: Returns a hash code for the variable.
- HasValue: Returns 1 (true) if the variable contains a given set of values.
- IsFinite: Returns 1 (true) if all of the values in the variable are finite.
- IsInfinite: Returns 1 (true) if all of the values in the variable are infinite.
- IsNaN: Returns 1 (true) if all of the values in the variable are NaN.
- IsReal: Returns 1 (true) if the variable is not a complex data type.
- Map: Pass all data values through a user-defined function or Lambda function.
- NestedMap: Use a nested loop to pass the data values and arguments through a user function.
- PtrValid: Returns the validity of its pointer arguments, or alternatively returns a vector of pointers to all the existing valid pointer heap variables.
- Reduce: Use a user-defined function or Lambda function to cumulatively combine all values from left to right and return a single value.
- Reform: Change the array dimensions.
- Shift: Shift array elements along a dimension.
- Sort: Returns a sorted copy of the array.
- ToBits: Converts the variable to an array of bits.
- ToDouble: Converts the variable to type DOUBLE.
- ToInteger: Converts the variable to type LONG.
- ToList: Converts the variable to a LIST.
- ToString: Converts the variable to type STRING.
- Uniq: Returns a sorted copy of the array with all duplicates removed.

# IDL_Variable::Compare

IDL_Variable::Compare compares one variable to another and return –1 if the value is smaller, 0 if the values are equal, or +1 if the value is larger.

*Note: *The Compare method uses the same rules as the relational operators (LT, GT, etc.) when comparing values. For example, for strings, the method walks through each character of the two strings until it finds a difference in the byte values. For complex numbers, the absolute value is used for the comparison.

*Note: *If the two variables are different types, the values will be promoted to the larger type using IDL's standard rules of type promotion.

*Note: *You can not use the Compare method with pointers.

*Tip: *The Compare method is useful when constructing comparison functions for IDL_Variable::Sort.

## Examples

Compare one string to another:

`a = "cap"`

PRINT, a.Compare("cat")

IDL prints:

` -1`

Compare an array variable with a scalar:

a = [10,3,7,5,11]

PRINT, a.Compare(5)

IDL prints:

1 -1 1 0 1

## Syntax

*Result* = *var*.Compare( *Arg* )

## Return Value

The result is always a variable of type INT containing the values –1, 0, or +1. If both *var* and *Arg* are scalars then the result is an integer scalar. If one of the arguments is a scalar and the other is an array, then the scalar is matched up against each value of the array and the result is an integer array of the same dimensions. If both arguments are arrays then the result is an integer array with dimensions equal to whichever array has the smaller number of elements.

## Arguments

### Arg

The variable to compare against.

## Keywords

None

# IDL_Variable::Convert

The IDL_Variable::Convert method converts the variable to a different data type. This method is equivalent to calling the FIX function with the appropriate TYPE keyword value.

## Examples

Convert a float array to an integer array:

var = FINDGEN(5)

`; We could also use TYPE=3 instead of /LONG`

`newvar = var.Convert(/LONG)`

`HELP, newvar`

IDL prints:

`NEWVAR LONG = Array[5]`

Now convert a string array to double-precision floats:

var = ['3.14', '1.23', '-1d100']

`newvar = var.Convert(/DOUBLE)`

`PRINT, newvar`

IDL prints:

3.1400000 1.2300000 -1.0000000e+100

## Syntax

*Result* = *var*.Convert( KEYWORD=*keyword* )

## Return Value

The result is a scalar or array of the same dimensions as the variable with each element converted to the new data type.

## Arguments

None.

## Keywords

You must specify either the TYPE keyword or one of the individual type keywords.

### TYPE

Set this keyword to an integer giving the IDL type code to convert to. Possible values are:

- 1 - BYTE
- 2 - INT
- 3 - LONG
- 4 - FLOAT
- 5 - DOUBLE
- 6 - COMPLEX
- 7 - STRING
- 9 - DCOMPLEX
- 12 - UINT
- 13 - ULONG
- 14 - LONG64
- 15 - ULONG64

### BYTE, INT, LONG, FLOAT, DOUBLE, COMPLEX, STRING, DCOMPLEX, UINT, ULONG, L64, UL64

Instead of using the TYPE keyword, you can set one of these keywords to convert your variable to that type.

# IDL_Variable::Diff

IDL_Variable::Diff returns the number of unique elements which have been added or removed from a variable. The actual values can be captured with output keywords.

## Examples

Imagine we have a list of files:

file_list = ['file_1.dat','file_2.dat','/processed/file.dat']

Sometime later, we want to find out if our list of files has changed:

file_list_new = ['file_2.dat','file_3.dat', $

'/processed/file.dat','/processed/file_1.dat']

`count = file_list.Diff( file_list_new, ADDED=add, REMOVED=remove )`

The value for count, add, and remove are:

`PRINT, /IMPLIED, count, add, remove`

IDL prints:

3

file_3.dat

/processed/file_1.dat

file_1.dat

## Syntax

*Result* = *var*.Diff( Arg, ADDED=*variable*, REMOVED=*variable*, NADDED=*variable*, NREMOVED=*variable*)

## Return Value

The result is a scalar value representing the number of unique elements which have changed (i.e., the sum of NADDED and NREMOVED).

## Arguments

### Arg

The comparison array.

## Keywords

### ADDED

A named variable that will contain the values which are present in *Arg* but not in the variable.

### NADDED

A named variable that will contain the number of values in ADDED.

### REMOVED

A named variable that will contain the values which are present in the variable but not in *Arg*.

### NREMOVED

A named variable that will contain the number of values in REMOVED.

# IDL_Variable::Dup

The IDL_Variable::Dup method duplicates a scalar value and returns an array with the given dimensions. This is equivalent to the REPLICATE function, except for inputs of type string, where the ::Dup method joins together the strings across the first dimension.

## Examples

`IDL> a = 1.23`

IDL> b = a.Dup(5,2)

IDL> b.dim

5 2

`IDL> print, b`

1.23000 1.23000 1.23000 1.23000 1.23000

1.23000 1.23000 1.23000 1.23000 1.23000

`IDL> a = '*'`

IDL> print, a.Dup(10)

**********

IDL> b = a.Dup([6,5,2])

IDL> b.dim

5 2

`IDL> print, b`

****** ****** ****** ****** ******

****** ****** ****** ****** ******

## Syntax

*Result* = *var*.Dup( *Dim* )

## Return Value

Returns an array of the given dimensions, with the same type as *var*. If *var* is type string then the result is a string array of one less dimension than *Dim*, where *Dim[0]* indicates the number of copies of *var* in each element.

## Arguments

### Dim

A scalar expression or a vector of up to eight elements containing the dimensions of the result.

## Keywords

None

# IDL_Variable::Equals

The IDL_Variable::Equals method returns 1 (true) if the variable is equal to the supplied input argument. The ::Equals method uses the same rules as the ARRAY_EQUAL function:

- If both variables are arrays then they must have the same number of elements, and all of the corresponding elements must be equal.
- If one variable is an array and the other is a scalar, then every element of the array must be equal to that scalar value.
- If both variables are scalars then the values must be equal.

For all cases, if the data types are different, then the ::Equals method does automatic type promotion before comparing the values.

## Examples

Compare two arrays of different data types:

var1 = [1.0, 2.0, 3.0, 4.0]

var2 = [1, 2, 3, 4]

PRINT, var1.Equals(var2)

IDL prints:

1

Compare an array and a scalar:

var = STRARR(100)

PRINT, var.Equals("")

IDL prints:

1

## Syntax

*Result* = *var*.Equals(*Value*, TOLERANCE=*value* )

## Return Value

A boolean value of 0 (false) or 1 (true).

## Arguments

### Value

An IDL variable to compare to *var*.

*Tip: *If you are comparing an array to a scalar, you should make sure that the scalar has the same data type as the array. If the scalar is a more precise data type, then ::Equals will convert the entire array to that type before doing the comparison.

## Keywords

### TOLERANCE

By default, ::Equals will return true if the corresponding elements in each operand are exactly equal. Set the TOLERANCE keyword to a non-zero number to instead treat values as being equal if they are within the tolerance value from each other. If the type of the tolerance variable is not the same as the input arguments, it will be converted to the appropriate type. For each pair of elements, *X*_{i} and *Y*_{i}, the pair is considered equal if |*X*_{i} − *Y*_{i}| <= |*T*|, where |*T*| is the absolute value of the tolerance.

*Note: *The TOLERANCE keyword is not allowed for input arguments of type string, pointer reference, or object reference.

*Note: *Setting TOLERANCE=0 is the same as not specifying the keyword.

# IDL_Variable::Filter

The IDL_Variable::Filter method passes each data value through a boolean filter function or Lambda function and returns only values that pass the test.

## Examples

Create a new file called myfilterfunction.pro that keeps only prime numbers:

`function myfilterfunction, value`

return, value le 3 || MIN(value mod [2:FIX(SQRT(value))])

`end`

Use your function to return only the prime numbers in an array:

var = [2:50]

newvar = var.Filter('myfilterfunction')

`PRINT, newvar`

IDL prints:

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47

Now use a Lambda function to avoid creating a separate routine:

var = [2:50]

newvar = var.Filter(Lambda(n:n le 3 || MIN(n mod [2:FIX(SQRT(n))])))

*Tip: *The COMPILE_CODE procedure can be used to generate functions on the fly.

## Syntax

*Result* = *var*.Filter( *Function*, *Args* , /VECTOR )

## Return Value

The result is a vector of the same type as the input containing only the values where the filter function returned a non-zero number for that input value. If none of the values are good then the method returns !NULL.

## Arguments

### Function

A string or Lambda expression giving the name of the user-defined function to call for each value. For user-defined functions, your function should have the form:

`function myfunction, value`

result = ...

` return, result`

`end`

The result should be a scalar value containing a non-zero value if the input value "passes" your filter test, and a zero value if the input value "fails" your filter test.

### Args

You can specify any number of additional arguments to be passed on to your filter or Lambda function. Each argument must be either a scalar or an array of the same length as your input. For scalar arguments, ::Filter will pass in that same scalar value to each call of the filter function. For vector arguments, ::Filter will pull out the value corresponding to the current input value and pass that into your filter function as a scalar.

## Keywords

### VECTOR

Set this keyword if your *Function* is "vectorized". In other words, it will give the same result if all of the values are passed in at once instead of looping over each value. By default, IDL will pass in each value as a separate call.

# IDL_Variable::Finite

The IDL_Variable::Finite method returns an array containing only the finite values within the variable. A value is finite if it is not equal to NaN (not-a-number) or infinity.

This method is equivalent to calling var[WHERE(FINITE(*var*), /NULL)].

*Note: *If the input variable is type integer or string then the method returns the original variable.

## Examples

var = FINDGEN(10, 20)

`newvar = var.Finite( )`

`HELP, newvar`

`; Now make some values be non-finite.`

var[[5, 10, 15, 20]] = !VALUES.F_NaN

`newvar = var.Finite( )`

`HELP, newvar`

IDL prints:

NEWVAR FLOAT = Array[10, 20]

`NEWVAR FLOAT = Array[196]`

## Syntax

*Result* = *var*.Finite( )

## Return Value

If every element of the input variable is finite, then the result is an array of the same type and dimensions as the input. If the input contains any non-finite elements, then the result is a one-dimensional array (a vector) containing only the finite values.

If none of the values are finite then the result is set to !NULL.

## Arguments

None.

## Keywords

None.

# IDL_Variable::FromBits

The IDL_Variable::FromBits method converts a variable from its bit representation to a scalar value or an array of values.

## Example

`var = "IDL"`

newvar = var.ToBits()

`HELP, newvar`

var1 = newvar.FromBits(/BYTE)

var2 = newvar.FromBits(/STRING)

`PRINT, var1, var2`

IDL prints:

NEWVAR BYTE = Array[8, 3]

73 68 76

IDL

## Syntax

*Result* = *var*.FromBits( )

## Return Value

Assume that the input variable has dimensions [N, D_{1}, D_{2}, ...], where N is the number of bits per element (usually a multiple of 8) and [D_{1}, D_{2}, ...] are the additional dimensions. The result is then an array of dimensions [D_{1}, D_{2}, ...].

If the input variable is just a vector of length N then the result is a scalar.

By default the result will have type LONG, unless one of the type keywords is set.

## Arguments

None.

## Keywords

You can specify either the TYPE keyword or one of the individual type keywords. If you do not set any keywords then type LONG is used.

### TYPE

Set this keyword to an integer giving the IDL type code of the result. Possible values are:

- 1 - BYTE
- 2 - INT
- 3 - LONG
- 4 - FLOAT
- 5 - DOUBLE
- 7 - STRING
- 12 - UINT
- 13 - ULONG
- 14 - LONG64
- 15 - ULONG64

### BYTE, INT, LONG, FLOAT, DOUBLE, STRING, UINT, ULONG, L64, UL64

Instead of using the TYPE keyword, you can set one of these keywords to return a variable of that type.

# IDL_Variable::Hashcode

The IDL_Variable::Hashcode method returns an unsigned integer (32-bit) hash code for the variable's value. The hash code is computed using Bob Jenkins' One-At-A-Time hash, downloaded from http://www.burtleburtle.net/bob/hash/doobs.html.

The hash code computation has the following properties:

- All numeric values (except complex) are converted to double-precision floating-point numbers. Therefore, all numbers which have the same value (regardless of IDL type) will produce the same hash. For example, 254b, 254L, and 254.0d will all produce the same hash code.
- Complex numbers (single or double precision) are converted to double-precision complex. Complex numbers which have a zero imaginary part will produce the same hash as their real value.
- Strings are case sensitive.
- For pointers the hash code is computed using the heap id number, and is not guaranteed to be the same across IDL sessions.
- Structures are not allowed.
- For arrays a single hash code is computed using all of the values. Two arrays with matching values will produce the same hash code. Arrays with different elements or elements in a different order will typically produce different hash codes, but this is not guaranteed since there are only 2
^{32}possible hash values. - Hash codes for numbers, strings, and arrays should not change across different platforms or IDL versions.

## Examples

`var1 = "abcd"`

`var2 = "dcba"`

PRINT, var1.Hashcode( )

PRINT, var2.Hashcode( )

IDL prints:

3448463878

` 1944347701`

## Syntax

*Result* = *var*.Hashcode( )

## Return Value

An unsigned long integer.

## Arguments

None.

## Keywords

None.

# IDL_Variable::HasValue

The IDL_Variable::HasValue method determines whether the array contains a given value or values.

## Examples

Determine whether a string array contains a specific set of values:

str = ['3', '1', '2', '5', '4']

PRINT, str.HasValue([1,2,3])

IDL prints:

1

## Syntax

*Result* = *var*.HasValue( *Value* )

## Return Value

A boolean value of 1 (true) or 0 (false). If the *Value* argument is an array, each of its values must be contained within *var* for the result to be true.

## Arguments

### Value

A scalar or array of any IDL data type except objects or structures.

*Tip: *You should make sure that *Value* has the same data type as the variable *var*. Otherwise, if the *Value* is a more precise data type, then ::HasValue will convert the entire *var* array to that type before doing the comparison.

## Keywords

None.

# IDL_Variable::IsFinite

The IDL_Variable::IsFinite method returns 1 (true) if every element of a variable is finite or 0 (false) if any element is NaN or Infinity.

## Examples

var1 = [1.0, 2.0, 3.0]

var2 = [1.0, !VALUES.F_NaN, 3.0]

PRINT, var1.IsFinite( ), var2.IsFinite( )

IDL prints:

1 0

## Syntax

*Result* = *var*.IsFinite( )

## Return Value

A boolean value of 0 (false) or 1 (true).

## Arguments

None.

## Keywords

None.

# IDL_Variable::IsInfinite

The IDL_Variable::IsInfinite method returns 1 (true) if every element of the variable is equal to Infinity or 0 (false) if any element is finite.

## Examples

var1 = !VALUES.D_Infinity

var2 = [1, 2, 3, !VALUES.F_Infinity]

PRINT, var1.IsInfinite( ), var2.IsInfinite( )

IDL prints:

1 0

## Syntax

*Result* = *var*.IsInfinite( )

## Return Value

A boolean value of 0 (false) or 1 (true).

## Arguments

None.

## Keywords

None.

# IDL_Variable::IsNaN

The IDL_Variable::IsNaN method returns 1 (true) if every element of the variable is equal to NaN or 0 (false) if any element is finite.

## Examples

var1 = !VALUES.F_NaN

`var2 = [!VALUES.F_NaN, !VALUES.F_NaN, 1.23, !VALUES.F_NaN]`

PRINT, var1.IsNaN( ), var2.IsNaN( )

IDL prints:

1 0

## Syntax

*Result* = *var*.IsNaN( )

## Return Value

A boolean value of 0 (false) or 1 (true).

## Arguments

None.

## Keywords

None.

# IDL_Variable::IsReal

The IDL_Variable::IsReal method returns 1 (true) if every element of the variable has a zero imaginary part.

*Note: *For non-complex data, ::IsReal will return 1 (true), without examining any of the data. For complex and double-complex data, each element is examined. If all of the elements have zero imaginary, then 1 (true) is returned. As soon as an element is reached that has a non-zero imaginary part, then 0 (false) is returned.

## Examples

`var1 = 255b`

var2 = [dcomplex(1, 0), dcomplex(2, 0)]

var3 = [dcomplex(1, 0), dcomplex(2, 1)]

PRINT, var1.IsReal(), var2.IsReal(), var3.IsReal()

IDL prints:

1 1 0

## Syntax

*Result* = *var*.IsReal( )

## Return Value

A boolean value of 1 (true) or 0 (false).

## Arguments

None.

## Keywords

None.

# IDL_Variable::Map

The IDL_Variable::Map method passes each data value through a user-defined function or Lambda function.

## Examples

Create a new file called mymapfunction.pro that returns a cubic polynomial:

`function mymapfunction, x, a, b, c`

return, (x - a)^3.0 + (x - b)^2 + (x - c)

`end`

Use your function to map an array to the new values:

var = [-2: 2: 0.01]

`; Each var value is passed in separately`

newvar = var.Map('mymapfunction', 1, 2, 0)

`PRINT, var, newvar`

IDL prints:

-2.00000 -1.99000 -1.98000 -1.97000 -1.96000 ...

-13.0000 -12.8008 -12.6032 -12.4072 -12.2127 ...

Now use a Lambda function to avoid creating a separate routine:

var = [-2: 2: 0.01]

`; Each var value is passed in separately`

newvar = var.Map(Lambda(x,a,b,c:(x-a)^3.0+(x-b)^2+(x-c)), 1, 2, 0)

This function is actually vectorizable, so we can use /VECTOR:

var = [-2: 2: 0.01]

lcubic = Lambda(x,a,b,c:(x-a)^3.0+(x-b)^2+(x-c))

`; All of the var values are pass in at once.`

newvar = var.Map(lcubic, 1, 2, 0, /VECTOR)

*Tip: *The COMPILE_CODE procedure can be used to generate functions on the fly.

## Syntax

*Result* = *var*.Map( *Function*, *Args* , /VECTOR )

## Return Value

If the user-defined function returns scalars, then the result is a variable of the same dimensions as the input. If the user-defined function returns an array, then the result is a variable with the combined dimensions of the function's result and the original input.

The data type of the result is determined by the first call to the *Function*.

## Arguments

### Function

A string or Lambda expression giving the name of the user-defined function to call for each value. For user-defined functions, your function should have the form:

`function myfunction, value`

result = ...

` return, result`

`end`

The result should be a scalar value.

### Args

You can specify any number of additional arguments to be passed on to your user-defined function or Lambda function. Each argument must be either a scalar or an array of the same length as your input. For scalar arguments, ::Map will pass in that same scalar value to each call of the function. For vector arguments, ::Map will pull out the value corresponding to the current input value and pass that into your function as a scalar.

## Keywords

### VECTOR

Set this keyword if your *Function* is "vectorized". In other words, it will give the same result if all of the values are passed in at once instead of looping over each value. By default, IDL will pass in each value as a separate call.

## More Examples

Construct a mapping that returns a three-element array for each input value containing the original value along with the sine and cosine:

a = [1:100]

r = a.Map(Lambda(a: [a, sin(a), cos(a)]))

`HELP, r`

IDL prints:

R FLOAT = Array[3, 100]

We could also return the result as a structure array with three fields:

a = [1:100]

r = a.Map(Lambda(a: {Data: a, SinA: sin(a), CosA: cos(a)}))

`HELP, r`

`HELP, r.A, r.SINA, r.COSA`

IDL prints:

`R STRUCT = -> <Anonymous> Array[100]`

`<Expression> INT = Array[100]`

`<Expression> FLOAT = Array[100]`

`<Expression> FLOAT = Array[100]`

# IDL_Variable::NestedMap

The IDL_Variable::NestedMap method passes each array value along with up to eight other arguments through a user-defined function or Lambda function. Each array value is combined with every element from the other arguments using a nested loop. This operation also goes by the name "list comprehension" or "Cartesian product". You can also supply an optional filter function to remove unwanted results.

#### Difference between Map and NestedMap

Assume we have two arrays, a and b, with three elements each. For a given map function F(a,b):

a.Map(F, b) returns a vector containing:

[F(a[0], b[0]), F(a[1], b[1]), F(a[2], b[2])]

a.NestedMap(F, b) returns a 2D array containing:

[[ F(a[0], b[0]), F(a[1], b[0]), F(a[2], b[0]) ],

[ F(a[0], b[1]), F(a[1], b[1]), F(a[2], b[1]) ],

[ F(a[0], b[2]), F(a[1], b[2]), F(a[2], b[2]) ]]

## Example

Return a new array containing every combination of items from two array:

a = ['a', 'b', 'c']

b = ['d', 'e', 'f']

c = a.NestedMap(Lambda(x,y:x+y), b)

`HELP, c`

`PRINT, c`

IDL prints:

C STRING = Array[3, 3]

` ad bd cd`

ae be ce

af bf cf

## Syntax

*Result* = *var*.NestedMap( *Function*, *Args* , FILTER=*string*)

## Return Value

The result is an array containing the new values. The data type of the result is determined by the first call to the *Function*.

If FILTER is not supplied then the result is a multi-dimensional array, with each dimension given by the number of elements of *var* and each additional argument. For example, if *var* has 10 elements, *argument 1* has 7 elements, and *argument 2* has 4 elements, then the result is a [10, 7, 4] array.

If FILTER is supplied then the result is a vector containing all of the retained results. Note that even if *all* of the results survive the filter, the result will still be a vector.

## Arguments

### Function

A string or Lambda expression giving the name of the user-defined function to call for each value. For user-defined functions, your function should have the form:

`function myfunction, value, arg1, arg2, ...`

result = ...

` return, result`

`end`

### Args

You can specify up to eight additional arguments. Each argument must be either a scalar, array, or list of any length. For scalar arguments, ::NestedMap will pass in that same scalar value to each call of the function. For vector arguments, ::NestedMap will perform a nested loop over all elements of that argument plus all other arguments. The nested loop is performed from left to right across the arguments, starting with the original *var* variable.

## Keywords

### FILTER

Set this keyword to a string or Lambda expression giving the name of a user-defined filter function. The function should have the form:

`function myfilter, result`

good = some function of result...

return, good ? 1 : 0

`end`

This function will be called for each result value. The function should return 1 (true) if the result should be added to the *Result* array, 0 (false) if the result should be discarded, or –1 if the NestedMap should stop early and return just the results up to (but not including) that result.

## More Examples

Use a Lambda function to return triangles that satisfy the Pythagorean theorem. First construct a new array containing triplets of all combinations of numbers between 1 and 20:

x = [1:20]

p = x.NestedMap(Lambda(x,y,z:[x,y,z]), x, x)

`HELP, p`

IDL prints:

P INT = Array[3, 20, 20, 20]

This is not what we want. We need to keep only triplets that satisfy x^2 + y^2 = z^2. Use the FILTER keyword to keep only these values:

p = x.NestedMap(Lambda(x,y,z:[x,y,z]), x, x, $

FILTER=Lambda(r:r[2]^2 eq r[0]^2+r[1]^2))

`HELP, p`

PRINT, p[*, 0:1] ; print the first two triplets

IDL prints:

P INT = Array[3, 12]

4 3 5

3 4 5

This still isn't what we want because it has duplicate triplets. Change the filter function to exclude duplicates:

p = x.NestedMap(Lambda(x,y,z:[x,y,z]), x, x, $

FILTER=Lambda(r:(r[0] le r[1]) && (r[2]^2 eq r[0]^2+r[1]^2)))

`HELP, p`

`PRINT, p`

IDL prints:

P INT = Array[3, 6]

3 4 5

6 8 10

5 12 13

9 12 15

8 15 17

12 16 20

*Tip: *The COMPILE_CODE procedure can be used to generate functions on the fly.

# IDL_Variable::PtrValid

The IDL_Variable::PtrValid method returns the validity of its pointer arguments.

## Examples

var = PTR_NEW(228l)

PRINT, var.PtrValid( )

IDL prints:

1

## Syntax

*Result* = *var*.PtrValid( )

## Return Value

A boolean value of 0 (false) or 1 (true). If *var* is not of type pointer, then 0 is returned. If *var* is an array then ::PtrValid returns an array of 0's and 1's.

## Arguments

None.

## Keywords

None.

# IDL_Variable::Reduce

The IDL_Variable::Reduce method passes each data value cumulatively from left to right through a user-defined function or Lambda function and returns a single result.

## Examples

Create a new file called myreducefunction.pro that adds up arrays (or concatenates strings):

`function myreducefunction, accumvalue, value`

` return, accumvalue + value`

`end`

Use your function on an integer array and a string array:

var = [1:100]

newvar = var.Reduce('myreducefunction')

`PRINT, newvar`

var = ['a','b','r','a','c','a','d','a','b','r','a']

newvar = var.Reduce('myreducefunction')

`PRINT, newvar`

IDL prints:

5050

abracadabra

Now use a Lambda function to avoid creating a separate routine:

var = ['a','b','r','a','c','a','d','a','b','r','a']

newvar = var.Reduce(Lambda(x,y:x+y))

Finally, use the /CUMULATIVE to return all of the intermediate results:

newvar = var.Reduce(Lambda(x,y:x+y), /CUMULATIVE, VALUE="IDL: ")

`PRINT, newvar`

IDL prints:

IDL: a

IDL: ab

IDL: abr

IDL: abra

IDL: abrac

IDL: abraca

IDL: abracad

IDL: abracada

IDL: abracadab

IDL: abracadabr

IDL: abracadabra

*Tip: *The COMPILE_CODE procedure can be used to generate functions on the fly.

## Syntax

*Result* = *var*.Reduce( *Function*, *Args*, /CUMULATIVE, VALUE=*value*)

## Return Value

The result is a value containing the cumulative result. The data type and dimensions of the result will depend upon your calling function's result type and dimensions.

If your input contains a single element then this value will be returned as the result without calling the function, unless the VALUE keyword is set, in which case the function will be called once.

*Tip: *You can use the /CUMULATIVE keyword to return all of the intermediate results instead of just the final result.

## Arguments

### Function

`function myfunction, accumvalue, value`

result = ...

` return, result`

`end`

The result should be a scalar value that combines the current accumulated value (the first argument) and the current input value (the second argument).

### Args

You can specify any number of additional arguments to be passed on to your user-defined function or Lambda function. Each argument must be either a scalar or an array of the same length as your input. For scalar arguments, ::Reduce will pass in that same scalar value to each call of the filter function. For vector arguments, ::Reduce will pull out the value corresponding to the current input value and pass that into your function as a scalar.

## Keywords

### CUMULATIVE

If this keyword is set, then the *Result* will be a vector containing all of the intermediate cumulative results instead of just the final result.

### VALUE

Set this keyword to the starting value. If this keyword is set then this value will be passed into your function along with the first element of your input. If this keyword is not set then the first two elements will be passed into your function.

# IDL_Variable::Reform

The IDL_Variable::Reform method changes the dimensions of an array without changing the total number of elements.

This method is equivalent to calling the REFORM function.

## Examples

var = FINDGEN(100)

`; This is equivalent to var.Reform([5, 20])`

newvar = var.Reform(5, 20)

`HELP, newvar`

IDL prints:

NEWVAR FLOAT = Array[5, 20]

Now remove a leading dimension of 1, replacing the original variable:

var = FLTARR(1, 20)

var = var.Reform(/OVERWRITE)

`HELP, var`

IDL prints:

`VAR FLOAT = Array[20]`

## Syntax

*Result* = *var*.Reform( /OVERWRITE )

or

*Result* = *var*.Reform( *Dimensions*, /OVERWRITE )

or

*Result* = *var*.Reform( *Dim1*, *Dim2*, *Dim3*, ..., /OVERWRITE )

## Return Value

An array of the specified dimensions.

## Arguments

If the Reform method is called with no arguments, then the method removes any dimensions of length 1 and returns.

You can specify the result dimensions as either a single argument containing a vector of dimensions, or as separate arguments, one for each dimension.

### Dimensions

Set this argument to a vector containing the new dimensions. The total number of elements must be the same as the original variable.

### Dim1

Set the *Dim1*, *Dim2*, ... arguments to integers giving the size of each dimension. The total number of elements must be the same as the original variable.

## Keywords

### OVERWRITE

Set this keyword to change the dimensions of the variable "in place" instead of making a copy.

*Tip: *For the OVERWRITE keyword to be effective, use the same name for the result variable as the input variable. For example:

myvar = FINDGEN(100)

myvar = myvar.Reform(10, 10, /OVERWRITE)

# IDL_Variable::Shift

The IDL_Variable::Shift method shifts elements of vectors or arrays along any dimension by any number of elements. Positive shifts are to the right while negative shifts are to the left. All shifts are circular: Elements shifted off one end wrap around and are shifted onto the other end.

This method is equivalent to calling the SHIFT function.

## Example

Take a two-dimensional array, and shift the columns 2 spaces to the left, and the rows down by 1.

var = BINDGEN(10, 5)

`PRINT, var`

PRINT, var.Shift(-2, 1)

`; we could also have done var.Shift([-2, 1])`

IDL prints:

0 1 2 3 4 5 6 7 8 9

10 11 12 13 14 15 16 17 18 19

20 21 22 23 24 25 26 27 28 29

30 31 32 33 34 35 36 37 38 39

40 41 42 43 44 45 46 47 48 49

42 43 44 45 46 47 48 49 40 41

2 3 4 5 6 7 8 9 0 1

12 13 14 15 16 17 18 19 10 11

22 23 24 25 26 27 28 29 20 21

32 33 34 35 36 37 38 39 30 31

## Syntax

*Result* = *var*.Shift( *S1*, *S2*, *S3*, ... )

## Return Value

An array of the same dimensions as the variable.

## Arguments

### S1, S2, S3, ...

The shift parameters. The *Si* arguments can be either a vector containing the shift parameters for each dimension, or a sequence of up to eight scalar shift values.

A shift specification of 0 means that no shift is to be performed along that dimension.

## Keywords

None.

# IDL_Variable::Sort

The IDL_Variable::Sort method returns a sorted copy of the input array using either IDL's built-in comparison rules or a user-defined compare function.

This method is equivalent to calling var[SORT(var)].

*Note: *String arrays are sorted using the ASCII collating sequence. Complex arrays are sorted by their magnitude. Array values which are NaN (not-a-number) are moved to the end of the result.

## Example

var = [0.7, 0.2, 0.4, 0.9, 0.0]

newvar = var.Sort( )

`PRINT, newvar`

IDL prints:

0.000000 0.200000 0.400000 0.700000 0.900000

## Syntax

*Result* = *var*.Sort( [COMPARE_FUNCTION=*string*] [, COUNT=*integer*] [, INDICES=*variable*] [, /REVERSE] )

## Return Value

A one-dimensional array (a vector) of the same type as the input, containing all of the sorted values.

If the input variable is a scalar then the variable is returned unchanged.

## Arguments

None.

## Keywords

### COMPARE_FUNCTION

A string or Lambda function giving the name of a user-defined "compare" function. The function should have the form:

`function myfunc, value1, value2`

The function should return –1 if value1 should be considered "less than" value2, +1 if value1 is "greater than" value2, or 0 if the two array elements are "equal". By default, the ::Sort method uses IDL's standard rules for comparing values.

*Note: *If *var* is a pointer array, then by default the Sort method will sort the pointer identifiers, not the actual data within the pointers. However, if you pass in a compare function, then IDL will instead de-reference the pointers and pass in the actual data values to your function. In this case, your comparison function must be able to handle any data types that could be contained within your pointer array.

### COUNT

Set this keyword to an integer giving the number of elements to sort. You can use this keyword to sort just the first part of an array.

### INDICES

Set this keyword to a named variable. On return this variable will contain a one-dimensional integer array of subscripts that were used to sort the original values. This variable is identical to the result of calling SORT(var).

*Note: *If the number of elements in the input variable is smaller than the largest 32-bit integer, then INDICES will contain 32-bit integers (type LONG), otherwise INDICES will contain 64-bit integers (type LONG64).

### REVERSE

Set this keyword to sort the array in reverse order.

## Examples

Do a sort of a string array, but use a compare function to sort on string length. First create a function:

`function string_compare, a, b`

` ; Return -1, 0, or 1 depending upon the string length`

return, (s1.Strlen()).Compare(s2.Strlen())

`end`

Now do the sort:

var = ['abcd', 'dcb', 'z', 'aa']

`newvar = var.Sort(COMPARE_FUNCTION='string_compare')`

`PRINT, newvar`

IDL prints:

z aa dcb abcd

Now do the same sort, but using a Lambda function:

lam = Lambda(a,b: (a.Strlen()).Compare(b.Strlen()))

newvar = var.Sort(COMPARE_FUNCTION=lam)

# IDL_Variable::ToBits

The IDL_Variable::ToBits method converts the variable to an array of bits.

## Example

var = [0b, 1b, 3b, 85b, 255b]

newvar = var.ToBits()

`HELP, newvar`

`PRINT, newvar`

IDL prints:

NEWVAR BYTE = Array[8, 5]

0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 1

0 0 0 0 0 0 1 1

0 1 0 1 0 1 0 1

1 1 1 1 1 1 1 1

## Syntax

*Result* = *var*.ToBits( )

## Return Value

For byte, integer, and floating-point data, the result is a byte array of dimensions [N, D_{1}, D_{2}, ...], N is the number of bits per element (either 8, 16, 32, or 64) and the [D_{1}, D_{2}, ...] are the dimensions of the original variable.

For string variables the result is a byte array of dimensions [8, M], where each character is converted to its extended-ASCII 8-bit representation, and M is the total number of characters within the entire string array.

Variables of type complex or type pointer will throw an error.

*Note: *This routine will only work with scalars or arrays up to 7 dimensions. Arrays with 8 dimensions will throw an error.

## Arguments

None.

## Keywords

None.

# IDL_Variable::ToDouble

The IDL_Variable::ToDouble method converts the variable to the double-precision data type.

This method is equivalent to calling the DOUBLE function.

## Example

var = ['3.14', '1.23', '-1d100']

`newvar = var.ToDouble( )`

`PRINT, newvar`

IDL prints:

3.1400000 1.2300000 -1.0000000e+100

## Syntax

*Result* = *var*.ToDouble( )

## Return Value

A scalar or array of the same dimensions as the variable.

## Arguments

None.

## Keywords

None.

# IDL_Variable::ToInteger

The IDL_Variable::ToInteger method converts non-integer variables to type LONG (32-bit signed). Integer variables are returned unchanged.

This method is equivalent to calling the LONG function if the variable is type floating point, complex, or string.

## Examples

var = ['-3.14', '1.23', '12.5']

PRINT, var.ToInteger( )

PRINT, var.ToInteger(/FLOOR)

PRINT, var.ToInteger(/CEIL)

PRINT, var.ToInteger(/ROUND)

IDL prints:

-3 1 12

-4 1 12

-3 2 13

-3 1 13

## Syntax

*Result* = *var*.ToInteger( [/CEIL] [, /FLOOR] [, /ROUND] )

## Return Value

A scalar or array of the same dimensions as the variable.

## Arguments

None.

## Keywords

*Note: *If no keywords are specified, the integer portion of each value is kept (for example, [12.9, -12.9] would equate to [12, -12]).

### CEIL

Set this keyword to return the ceiling, or the closest integer greater than or equal to the value. This is equivalent to calling the CEIL function.

### FLOOR

Set this keyword to return the floor, or the closest integer less than or equal to the value. This is equivalent to calling the FLOOR function.

### ROUND

Set this keyword to round each value. This is equivalent to calling the ROUND function.

# IDL_Variable::ToList

The IDL_Variable::ToList method converts the variable to a LIST. This method is equivalent to calling the LIST function with the EXTRACT keyword.

## Examples

Convert a string array to a list:

IDL> var = ['My data', '3.14', '1.23', '-1d100']

IDL> newvar = var.ToList()

IDL> newvar

IDL prints:

[

` "My data",`

` "3.14",`

` "1.23",`

` "-1d100"`

]

## Syntax

*Result* = *var*.ToList( [/NO_COPY] )

## Return Value

The result is a list with the same number of elements and data types as the original variable.

*Note: *Because lists are one-dimensional, multidimensional arrays will be collapsed to a single dimension.

## Arguments

None.

## Keywords

### NO_COPY

If this keyword is set then the original variable will be destoyed.

# IDL_Variable::ToString

The IDL_Variable::ToString method converts the variable to type STRING with an optional format. By default, for numeric input the ::ToString method removes all extra whitespace, unless you have specified your own *Format* argument.

## Examples

Convert a scalar number:

var = !Const.Pi

PRINT, var.ToString( )

PRINT, var.ToString("('Pi=',F7.5)")

IDL prints:

3.1415926535897931

`Pi=3.14159`

Convert an array of numbers:

var = [0:11]

HELP, var.ToString( )

HELP, var.ToString("(4I3)")

PRINT, var.ToString("(4I3)")

IDL prints:

`<Expression> STRING = Array[12]`

`<Expression> STRING = Array[3]`

0 1 2 3

4 5 6 7

8 9 10 11

## Syntax

*Result* = *var*.ToString( [*Format*] )

## Return Value

A scalar or array of the same dimensions as the variable. If the *Format* argument is set then the dimensions of the result will depend upon the format string.

## Arguments

### Format

A formatting string. See Using Formatted Input/Output.

## Keywords

None.

# IDL_Variable::Uniq

The IDL_Variable::Uniq method removes all duplicate values from the input array and returns an array containing only the unique elements, sorted into increasing order.

This method is equivalent to calling var[UNIQ(var, SORT(var))].

*Note: *String arrays are sorted using the ASCII collating sequence. Complex arrays are sorted by their magnitude. Array values which are NaN (not-a-number) are moved to the end of the result.

## Example

Construct an array of 1000 elements, containing the values 0...9. Then remove all duplicates.

var = LONG(10 * RANDOMU(seed, 1000))

`PRINT, var`

newvar = var.Uniq( )

`PRINT, newvar`

IDL prints:

4 6 6 7 3 8 4 8 3 6 5 5 6 8 3 8 1 6 6 1 ...

0 1 2 3 4 5 6 7 8 9

## Syntax

*Result* = *var*.Uniq( /NO_SORT )

## Return Value

A one-dimensional array (a vector) of the same type as the input, containing only the unique values.

If the input variable is a scalar then the variable is returned unchanged.

## Arguments

None.

## Keywords

### NO_SORT

Set this keyword if the original variable is already sorted or you do not want ::Uniq to perform any sorting.

*Note: *The ::Uniq method works by examining neighboring values to see if they are equal, and then removing duplicates. If your original variable is not sorted, you may get unexpected results if you set NO_SORT.

# IDL_Variable::Where

IDL_Variable::Where compares one variable to another and return an array of indices (or subscripts) where the two variables match. For numeric data you can also specify a tolerance.

*Tip: *This is similar to the WHERE function, but allows you to directly input the second comparison variable. For example:

a = [-5, 2, 2, 7, 2, 8]

x = where(a eq 2) ; old way

x = a.where(2) ; new way

## Examples

Find where an array matches a scalar value:

IDL> a = [-5, 2, 2, 7, 2, 8]

IDL> print, a.Where(2)

1 2 4

Compare an array with another array:

IDL> a = [-5, 2, 2, 7, 2, 8]

IDL> b = [-5, 6, 2, 7, 3, 8]

IDL> print, a.Where(b)

0 2 3 5

Compare an array with a scalar, but using a tolerance:

IDL> a = [1.8, 1.9, 2.0, 2.1, 2.2]

IDL> print, a.Where(2.0, tolerance=0.15)

1 2 3

## Syntax

*Result* = *var*.Where( *Arg* [COMPLEMENT=*variable*] [, TOLERANCE=*value*] )

## Return Value

The result is an integer array containing the indices (subscripts) where the input variable matches the Arg value(s). If the input variable contains 2^{31} or more elements then the result will be type LONG64, otherwise the result will be type LONG.

If *Arg* is a scalar then each element of *var* is compared to that scalar value. If *Arg* is an array, then each element of *var* is compared to the corresponding element in *Arg*. If the two arrays are not equal in length then the shortest length is used.

If *Arg* and *var* are not the same data type, then the values will be promoted to the larger type using IDL's standard rules of type promotion.

If there are no matches between the two, then a scalar !NULL is returned.

## Arguments

### Arg

The scalar or array variable to compare against.

## Keywords

### COMPLEMENT

Set this keyword to a named variable that receives the indices (subscripts) where the input variable and the *Arg* do not match. These are the subscripts that are not returned in *Result*. Together, *Result* and COMPLEMENT specify every subscript in the input variable. If all of the elements matched (*Result* contains all of the subscripts), then COMPLEMENT will be set to !NULL.

### TOLERANCE

By default, IDL_Variable::Where will return the indices where the corresponding elements in each operand are exactly equal. Set the TOLERANCE keyword to a non-zero number to instead treat values as being equal if they are within the tolerance value from each other. If the type of the tolerance variable is not the same as the input arguments, it will be converted to the appropriate type. For each pair of elements, the pair is considered equal if the absolute value of their difference is less than or equal to the absolute value of the tolerance.

*Note: *The TOLERANCE keyword is not allowed for input arguments of type string, pointer, or object.

*Note: *Setting TOLERANCE=0 is the same as not specifying the keyword.

## Version History

8.4 |
Introduced |

8.5 |
Added ::ToList method |

8.8.3 |
Added TOLERANCE keyword to ::Equals method |

9.1 | Added ::Where method |

## See Also

Static Methods and Attributes, Variable Attributes, IDL_Integer, IDL_Number, IDL_Pointer, IDL_String, ISA, Lambda