Forum Discussion

Anonymous's avatar
Anonymous
Not applicable
5 years ago
Solved

Recursive function returns: Evaluation resulted in a stack overflow and cannot continue

Hi there,  

I am trying to build a function that goes through a column/list and checks whether the data stored is of type record or list. The function is below: 
- - - - - - - - - - - - - - - - - -
fx ColumnChecker =

let
  Source = (ListToRead as list, optional iterator as number) =>
    let
      RowCount = List.Count(ListToRead),
      i = if iterator = null then 0 else iterator,
      ListTypeCheck = Type.Is(Value.Type(ListToRead{i}), type list),
      RecordTypeCheck = Type.Is(Value.Type(ListToRead{i}), type record),
      Looper = try

          if ListTypeCheck then
            1

          else
 if RecordTypeCheck then
            2

          else
 if i >= RowCount then
            0

          else

            ColumnChecker(ListToRead, i + 1)
      otherwise
        error i
    in

      Looper
in

  Source

- - - - - - - - - - - - - - - - -
The function works fine on columns that actually contain lists or records but gives me the following error on columns that contain just text/number values: 

 

Here is the column in question that is throwing the error: 


The result I'm expecting to get is that since the column has no record/list entries, variable i will iterate until it surpasses the RowCount ("else if i >= RowCount") at which point it will exit the loop and return 0. This process works when I put in a static number ("else if i >= 50") but I need it to be dynamic and adjust to the size of the list being passed to the function. When debugging, the error was thrown whenever i reached the RowCount (try...otherwise error returned 348, which is the # of rows in the test data I was using)


Thanks for the help. 

ImkeFGreg_Deckler edhans mahoneypat 
  • If I understand your use case, here is one way to do it.  I made this this list and called it ListToCheck

     

    = {1,"text", {1..3}, [A="text"]}

     

    Then used this expression that returned a value of 2 (1 list and 1 record).

     

    = List.Count(List.Select(List.Transform(ListToCheck, each Value.Is(_, List.Type) or Value.Is(_, Record.Type)), each _ = true))

     

    If that works, you can convert it to a function with (didn't check this one but I think it will work)

     

    (listname as list) =>

    let

    x = List.Count(List.Select(List.Transform(listname, each Value.Is(_, List.Type) or Value.Is(_, Record.Type)), each _ = true))

    in

    x

     

    Pat

1 Reply

  • mahoneypat's avatar
    mahoneypat
    Microsoft Employee

    If I understand your use case, here is one way to do it.  I made this this list and called it ListToCheck

     

    = {1,"text", {1..3}, [A="text"]}

     

    Then used this expression that returned a value of 2 (1 list and 1 record).

     

    = List.Count(List.Select(List.Transform(ListToCheck, each Value.Is(_, List.Type) or Value.Is(_, Record.Type)), each _ = true))

     

    If that works, you can convert it to a function with (didn't check this one but I think it will work)

     

    (listname as list) =>

    let

    x = List.Count(List.Select(List.Transform(listname, each Value.Is(_, List.Type) or Value.Is(_, Record.Type)), each _ = true))

    in

    x

     

    Pat