Extract Function

Certified Associate Developer

Hi All I have requirement to get the values between  square brackets iam achieving it with the help of  extract function but when i was trying to insert the brackets after entering value and if my text value has uneven number of brackets it is erroring out

  

can you suggest is their any other alternate way to achieve this 

  Discussion posts and replies are publicly visible

Parents
  • I would encourage you to validate the incoming string before you attempt to use the extract() function on it. There are probably a few ways to do this but in essence if you check that the string you want to process contains an even number of "[" and "]" characters then you'll avoid the error. What might be a bit harder to achieve is to ensure that every "[" has a following "]" without another intervening "["...if that even matters to you? But the principle here: don't attempt to process data that is effectively invalid.

  • 0
    Certified Associate Developer
    in reply to Stewart Burchell

    Is there any function to count the number of "[" 

  • 0
    Certified Lead Developer
    in reply to tejashwinin0822

    you'll want to check out standard appian expression functions like "find()" to help with that.

    edit: find() doesn't actually work for this (grumble) but i believe my example below will.

  • Not directly, no. You have to break up the string into an array containing its individual characters and then you can count. Here's something that I played with:

    a!localVariables(
      local!stringAsArray: fn!char(fn!code(ri!myString)),
      local!scoring: a!forEach(
        items: local!stringAsArray,
        expression: a!match(
          value: fv!item,
          equals: "[",
          then: 1,
          equals: "]",
          then: - 1,
          default: 0
        )
      ),
      local!scoreSum: fn!sum(local!scoring),
      local!statusCode: if(local!scoreSum = 0, 1, 0),
      local!result: if(
        local!scoreSum = 0,
        fn!extract(ri!myString, "[", "]"),
        "INPUT ERROR"
      ),
      a!map(
        statusCode: local!statusCode,
        result: local!result
      )
    )

    Explanation:

    1. fn!char(fn!code(ri!myString)) generates the array of individual characters as described
    2. the a!forEach() then assigns a score for each character
    3. we then sum the individual scores - if there are an even number of "[" and "]" the score will be zero
    4. we then return an a!map() with the result. This contains a statusCode to indicate if the original string was valid or not, and a result

    Hope this makes sense

Reply
  • Not directly, no. You have to break up the string into an array containing its individual characters and then you can count. Here's something that I played with:

    a!localVariables(
      local!stringAsArray: fn!char(fn!code(ri!myString)),
      local!scoring: a!forEach(
        items: local!stringAsArray,
        expression: a!match(
          value: fv!item,
          equals: "[",
          then: 1,
          equals: "]",
          then: - 1,
          default: 0
        )
      ),
      local!scoreSum: fn!sum(local!scoring),
      local!statusCode: if(local!scoreSum = 0, 1, 0),
      local!result: if(
        local!scoreSum = 0,
        fn!extract(ri!myString, "[", "]"),
        "INPUT ERROR"
      ),
      a!map(
        statusCode: local!statusCode,
        result: local!result
      )
    )

    Explanation:

    1. fn!char(fn!code(ri!myString)) generates the array of individual characters as described
    2. the a!forEach() then assigns a score for each character
    3. we then sum the individual scores - if there are an even number of "[" and "]" the score will be zero
    4. we then return an a!map() with the result. This contains a statusCode to indicate if the original string was valid or not, and a result

    Hope this makes sense

Children
  • 0
    Certified Lead Developer
    in reply to Stewart Burchell

    That's a neat little parser.  I would have probably just resorted to splitting the original string on "[", then checking the members of the resulting array for the presence of "]" (i.e. each having at least 1 and only 1), and handling from there.

  • Yeah, I'm not convinced...a true parser would ensure that every opening "[" had a corresponding "]". The "parser" above just ensures there's an even number, which isn't the same. Open to suggestions how to achieve a true parser here...?

  • 0
    Certified Lead Developer
    in reply to Stewart Burchell
    Open to suggestions how to achieve a true parser here...?

    It's hard to say, really - there are too many unanswered questions about what the source data might be, and those things are required in order to form the initial assumptions behind a robust parser.  Without wasting the time actually trying, i'd guess it might be easier to make an exact one using regEx matching, though checking for potentially unlimited repeats can get pretty frustrating there.

  • 0
    Certified Associate Developer
    in reply to Stewart Burchell

    a!localVariables(
    local!datacontent: fn!char(
    fn!code(ri!text)
    ),
    local!sum: a!forEach(
    items: local!datacontent,
    expression: a!match(
    value: fv!item,
    equals: "[",
    then: 1,
    equals: "]",
    then: - 1,
    default: 0
    ),

    ),
    local!totalSum: fn!sum(local!sum),
    local!statusCode: if(local!totalSum = 0, 1, 0),
    local!result: union(
    if(
    local!totalSum = 0,
    fn!extract(
    ri!text,
    "[",
    "]"
    ),
    ""
    ),
    touniformstring({})
    ),
    {
    if(
    local!statusCode = 1,
    "",
    "Number of open square brackets and close square brackets must be equal"
    ),
    if(
    a!forEach(
    items: local!result,
    expression: find("[", fv!item)
    ),
    "No square brackets is allowed between [ and ]",
    ""
    )
    }
    )   in addition to your solution just added  find("[", fv!item) this to validation to prevent "[" in between open and close square brackets Thanks Stewart and Mike for you time and suggestion