Search code examples
aws-step-functions

AWS Step Function: Comparing Items in Different Arrays


I have a step function where I'm trying to check if one or all items in array 1 match any item in array 2 but I am coming up blank.

The JSON is as below:

{
  "Data": {
    "Array1": [
      "X",
      "Y",
      "Z"
    ],
    "Array2": [
      "A",
      "B",
      "C"
    ]
  }
}

I have tried using States.ArrayContains as outlined in the AWS documentation but I think this compares the entire array as opposed to the individual items within against each other, code outlined below.

"Pass": {
  "Type": "Pass",
  "End": true,
  "Parameters": {
    "contains.$": "States.ArrayContains($.Array2, $.Array1)"
  },
  "InputPath.$": "$.Data"
}

I also had the idea to separate the above code into key,value pairs in the array and then using the Map item but am a but confused as to how to set this up since there are two different arrays:

{
  "Data": {
    "Array1": [
      {
        "item": "X"
      },
      {
        "item": "Y"
      },      
      {
        "item": "Z"
      }
    ],
    "Array2": [
      {
        "item": "A"
      },
      {
        "item": "B"
      },
      {      
        "item": "C"
      }
    ]
  }
}

Solution

  • You have the right idea. Iterate over the items in Array1 with a Map State and look for overlaps with States.ArrayContains.

    Parameters customizes the input to each iteration: an Item and Array2. The ItemProcessor is a Pass State that looks for the Item in Array2 with the States.ArrayContains intrinsic function. Each Pass state returns something like {"isInArray2" : false}, which is output from the Map as an array. The ResultsSelector summarizes the array output. It looks for trues. There is an overlap if any of the items is true.

    {
      "Comment": "Are there items in Array1 that are also in Array2?",
      "StartAt": "FindOverlaps",
      "States": {
        "FindOverlaps": {
          "Type": "Map",
          "InputPath": "$.Data",
          "Parameters": {
            "Item.$": "$$.Map.Item.Value",
            "Array2.$": "$.Array2"
          },
          "ItemProcessor": {
            "ProcessorConfig": {
              "Mode": "INLINE"
            },
            "StartAt": "FindRunning",
            "States": {
              "FindRunning": {
                "Type": "Pass",
                "Parameters": {
                  "isInArray2.$": "States.ArrayContains($.Array2, $.Item)"
                },
                "End": true
              }
            }
          },
          "End": true,
          "ResultSelector": {
            "hasOverlaps.$": "States.ArrayContains($..isInArray2, true)"
          },
          "ResultPath": "$.findOverlaps",
          "ItemsPath": "$.Array1"
        }
      }
    }
    

    For the input in the OP, which has no overlap, the output would be:

    "findOverlaps": {
        "hasOverlaps": false
    }