Getting One Property Value From Dictionary Based Upon Another Property Value

I have this expression rule and I need to get the value of one of the keys based upon whether another key property is true or false, I have this but doesn't work:

a!localVariables(
  local!myDictionary: {
    {
    item: 1,
    active: true,
    description: "Widget",
    color: "Green"}
    ,{
    item: 2,
    active:false,
    description: "another",
    color: "red"}
  },
  if(
  fn!index(local!myDictionary,"active","") == true,
    fn!index(local!myDictionary,"color",null), "")
)

To explain further: I would want to return the value "Green" from the key property color due to active property being true and not the value "red" because active property is false.

  Discussion posts and replies are publicly visible

Parents
  • +1
    Certified Lead Developer

    Close. There are a couple of notes. You should use a!map() instead of dictionaries to help resolve typing mismatch errors. With a dictionary you are probably getting a compare error with a list of variant and boolean. so that line should be more like 

    if(toboolean(fn!index(local!myDictionary,"active","")),

    Note: "if(predicate = true," and "if(predicate," are logically the same

    Line 15 will give you a boolean array of the indices where "active" is true, but wherever you return false, you will get "" returned, so your snippet would return {"Green", ""}. You could store this result and filter out the nulls using filter() or a!forEach(), but I would write this like:

    a!localVariables(
      local!myDictionary: {
        a!map(
          item: 1,
          active: true,
          description: "Widget",
          color: "Green"
        ),
        a!Map(
          item: 2,
          active:false,
          description: "another",
          color: "red"
        )
      },
      index(local!myDictionary.color, where(local!myDictionary.active), {})
    )

  • You could store this result and filter out the nulls using filter() or a!forEach(),

    Could this be a test case (forEach()) IF there were more than one true in the active property? Is this a correct assumption?

  • 0
    Certified Lead Developer
    in reply to here2learn

    Can your expand your question or give an example? I'm not sure what you are asking.

  • Sure: 

    a!localVariables(
      local!myDictionary: {
        a!map(
          item: 1,
          active: true,
          description: "Widget",
          color: "Green"
        ),
        a!Map(
          item: 2,
          active:false,
          description: "another",
          color: "red"
        ),
        a!Map(
          item: 3,
          active:true,
          description: "another des",
          color: "blue"
        )
      },
      index(local!myDictionary.color, where(local!myDictionary.active), {})
    )

    When you mentioned that you would save the results in a forEach() function, the above code now has two true items, in this instance, utilizing a forEach() would produce a list of {Green,Blue}. Is this correct?

  • 0
    Certified Lead Developer
    in reply to here2learn

    The example you just posted works just fine for your desired outcome.

    I was saying you would need a looping function to filter out nulls in your first example if you were to use if(). The if() approach would result in "{"Green", "", "Blue"}". If you wanted just "{"Green", "Blue"}", you would need to get rid of that middle "" element. Here is that example:

    a!localVariables(
      local!myDictionary: {
        {
          item: 1,
          active: true,
          description: "Widget",
          color: "Green"},
        {
          item: 2,
          active:false,
          description: "another",
          color: "red"}
      },
      local!tempResults: if(toboolean(fn!index(local!myDictionary,"active","")),
        fn!index(local!myDictionary,"color",null), 
        ""
      ),
      reject(fn!isnull, local!tempResults)
    )

    Note: At the risk of over-simplification, think of reject() as a specialized a!forEach() in this instance. 

Reply
  • 0
    Certified Lead Developer
    in reply to here2learn

    The example you just posted works just fine for your desired outcome.

    I was saying you would need a looping function to filter out nulls in your first example if you were to use if(). The if() approach would result in "{"Green", "", "Blue"}". If you wanted just "{"Green", "Blue"}", you would need to get rid of that middle "" element. Here is that example:

    a!localVariables(
      local!myDictionary: {
        {
          item: 1,
          active: true,
          description: "Widget",
          color: "Green"},
        {
          item: 2,
          active:false,
          description: "another",
          color: "red"}
      },
      local!tempResults: if(toboolean(fn!index(local!myDictionary,"active","")),
        fn!index(local!myDictionary,"color",null), 
        ""
      ),
      reject(fn!isnull, local!tempResults)
    )

    Note: At the risk of over-simplification, think of reject() as a specialized a!forEach() in this instance. 

Children