This is a question about the behavior of fn!index() function. The syntax is fn!i

This is a question about the behavior of fn!index() function. The syntax is fn!index(array, indices, defaultValToReturn).
The defaultValToReturn is of AnyType. Documentation mentions that default value should be of the same type as array elements. I find the behavior of index function strange in the below case:
fn!index( {4,5,6}, 1000, {}) -- As expected it returns a empty list i.e List of Variant since array size is less than 1000.
Now try, fn!index( {4,5,6}, {1000}, {} ) - This returns 4 - the first element in the array. I did not expect this result.
Now try, fn!index( {4,5,6}, {1000}, null ) - This returns nothing as expected.

Why does it behave in such manner for case 2? It always returns the first element whenever a multiple indices are provided and the default value is also an empty list.
Also try: fn!index({4,5,6}, {2,1000}, {}) - this returns 5,4. The 4 is the first element of the array.
I...

OriginalPostID-184786

OriginalPostID-184786

  • ...f anyone has insights into this behavior, and do not find it strange, please let me know the explanation.
  • When you use null / null() / 0 as default value it will work as expected .. But using {} is not correct as far as i have seen .. normally if you want to return a null value you should always use null() <whatever can be the datatype .. text, cdt, or anything> .. {} will actually initialize the variable on the left in some case (not in all case) ..

    But in this case, even using {} should not return first value .. May be a bug .. But always use null() for nullifing any data type object so that you have to check only isnull() later but if you use {} or "" you may also need to check length()=0 or len()=0 ..
  • To add to the above, it looks like when it's given an array of indices and an array of default values, for each element in the index array that is not found it will return the equivalent index in the default values array. If it runs out of elements in the default values array, it starts to return the elements of the first array. if you pass in an array of indexes and an empty array for defaults, it immediately runs out of elements in the default array and so returns an element of the first array for each index that is not found.

    Have a look at the following example, and add or remove elements to the defaults array to see the behaviour described above.

    index(
    {4,5,6},
    {7,1,34},
    {0,1}
    )
  • @kumaraveln, agreed about using null as default value. I just found above behavior strange.
  • Hi Chetan,
    fn!index({4,5,6}, 1000, {})
    {}(default value)--> The default value to be returned if the array or the index is invalid, i.e. if array itself is empty, or index is < 1 or > array.length.
    "The type of the default value must be same as that of elements of the array."
    Thatsway fn!index({4,5,6}, {2,1000}, {})---4,5 display two values

    for better understand
    index({4,5,6}, 1000, -9)-result is -9

    I think it will help u
  • @philb: You are right .. index( {4,5,6}, {100, 100 , 100}, {} ) returns 4,5,6 .. So when the default value is mentioned as an array (or empty array) and when it goes out of values, its starting to repeat the values in actual array .. kind of strange but not sure if it makes sense for any particular use case
  • @bhanuprakashm, the documentation does mention that the type of the default value must be the same as that of the elements of the array. However, it seems that internally the type of the default value and the type of the array elements is not compared when the index function executes. You can pass a default value which has a different data-type than the array elements. This maybe the cause of above strange behavior.
  • @philb, got your point. Interesting.
  • It also behaves differently when you're indexing a CDT or dictionary - for example:

    index(
    {one: 1, two: 2, three: 3},
    "badger",
    {}
    )

    ...behaves as you expect, and an array of string {"badger","mushroom"} just returns null regardless.
  • @philb, good observation. I observed one more thing. It seems we cannot specify multiple properties while getting cdt field values. This is different than how index works for primitive datatypes like number, Boolean etc.

    eg:This works: fn!index( {one: 1, two: 2, three: 3},
    "one",
    {}
    )
    But this does not: fn!index(
    {one: 1, two: 2, three: 3},
    {"one", "two"},
    {}
    )
    It always returns null when you specify multiple properties. You can make it work with apply.
    fn!apply(fn!index(
    {one: 1, two: 2, three: 3},
    _,
    {}
    ),

    {"one", "two"}
    )

  • Someone should probably add this discussion to the documentation :)
  • What should fn!index( {4,5,6}, {}, {} ) return? I was expecting an empty array ({}), but it returned all elements from the array ({4,5,6}). If that is correct, why fn!index( {4,5,6}, wherecontains({-1}, {4,5,6}), {} ) returns empty array? Did something change in latest versions of Appian for the index function?
  • In case 2, you are passing an array, so the internal algorithm may be cycling through the first array 4-5-6-4-5-6-4-5-6... Since 1000mod3 is 1, it returns index 1.
  • Chiming in to add that I just noticed this issue (in the case of "index({4, 5, 6}, {1000}, {})"), and it still seems to be unresolved as of Appian 18.2.  I had to work around it by making the default output to null() then removing nulls from the resulting array, which seems like kind of an unnecessary pain.

 Discussion posts and replies are publicly visible