Use of Filter function

Can someone explain the best use of filter function?

  Discussion posts and replies are publicly visible

  • 0
    Certified Lead Developer

    The documentation for filter() can be found over here - do you have any more specific questions?

  • ,

    Can this function be used to calculate the local variable local!output in my below piece of code?

    a!localVariables(
    local!data:{{
    id:1,
    value:"test",
    order:"new",
    active:true
    ),
    {
    id:2,
    value:"qa",
    order:"old",
    active:false
    )}
    },


    local!output:index(local!data,
    wherecontains(1,tointeger(local!data.id))),


    local!output
    )

  • 0
    Certified Lead Developer
    in reply to arunramanathtm

    filter() is tricky (and in my opionion should be used only when necessary) since you need to call it either on a system function or on an expression rule if you need something more customized.  For your use case (assuming i'm reading your code correctly), you would probably be better off using a!forEach().

    For instance:

    a!forEach(
      local!data,
      
      if(
        fv!item.id = 1,
        fv!item,
        {}
      )
    )

  • Personally I almost never use the filter() function. I use its inverse reject() more often because it allows you to easily remove nulls from a list:

    a!localVariables(
      local!test: {1, null, 3, null, 7},
      reject(
        fn!isnull,
        local!test
      )
    )

    As far as implementing behavior for filtering, I often use a method very similar to what you mentioned. The where function lets you define a boolean for each item in the list, so it makes it easier to use in a variety of scenarios. For example, suppose I want to return all the items with a cost over 100:

    a!localVariables(
      local!data:{
        {
          id: 3,
          name: "Item 1",
          cost: 50
        },
        {
          id: 2,
          name: "Item 2",
          cost: 120
        },
        {
          id: 4,
          name: "Item 3",
          cost: 75
        },
        {
          id: 7,
          name: "Item 4",
          cost: 150
        },
      },
      index(
        local!data,
        where(
          tointeger(local!data.cost)>100
        ),
        {}
      )
    )

    If you want more complex logic, you can replace line 27 with whatever expression you want that returns a boolean and it should allow you to filter the data as needed.

  • 0
    Certified Lead Developer

    Filter and reject go the way of most of the looping functions in the wake of the vast superiority of a!forEach.

    It's still useful sometimes.  It can make an exceptionally short, readable, nice bit of code when you want to use a helper rule you wrote (which outputs a boolean) on a list of items.

    filter(rule!myBooleanRule, local!myList, ri!extraParameterThatsAlwaysTheSame)

    If you have 2 inputs that change each iteration, now you've got to use the merge function to merge 2 arrays, now you might need partial evaluation with underscores _, now it's getting really hairy and you might just want a!forEach.

    You can use a!forEach always to mimic filter or reject, making them essentially worthless unless they're part of legacy code.  No need to remove them, so worth understanding how they work.  But no real need to use them either.

    I find that the looping functions are all sort of redundant and a little clunky now, except for the reduce() function.  all() or none() function might be a little easier to pull out than crafting a special a!forEach I suppose.  But I never used those before or after a!forEach.

  • 0
    Certified Lead Developer
    in reply to Dave Lewis

    As an aside: reject() does one thing that a!forEach() can't handle for whatever reason, which is to create an empty array when all members of said array are rejected.  a!forEach does this until the array is almost empty, by returning an empty set for each member of the array that gets "rejected", but then if it actually gets empty (ie all members are rejected), the result becomes a list of empty sets [iirc] instead of a single empty list.  Meaning that, in the global utility expression rule I often create that strips blank entries from arrays, i still have to use reject(), sadly.

  • 0
    Certified Lead Developer
    in reply to Mike Schmitt

    Feels like a!flatten needs to be used a little bit more frequently than I would like

  • 0
    Certified Lead Developer
    in reply to Dave Lewis

    I seem to remember even trying that and it not solving the issue I had.  But now that I try it, it looks like it might just.  Thanks.