Skip to main content
Known Participant
Jan 5, 2024 3:52 PM UTC
Solved

Most efficient way to remove duplicates in an array of CDT or Map based on a specific key?

I need to check a specific field in an array of cdt or map for duplicates, and return an array of cdt or map without duplicates on that field. For example:

CDT Array:

{
type!example(

email: "hello@gmail.com",

type: 1,

date: 01/01/2022

),

type!example(

email: "hello11@gmail.com",

type: 1,

date: 03/02/2023

),

type!example(

email: "hello@gmail.com",

type: 2,

date: 01/02/2023

)

}

In the above case, I want to return an array with unique email fields. Since the first and third item in the array have the same email address "hello@gmail.com", I only want to return the first one.

    Inspiring
    Jan 5, 2024 4:11 PM UTC

    Hi,
    Following Stefan's suggestion, I have employed the 'unique' function and 'forEach' loop to retrieve the CDTs. Please refer to the code snippet below:

    a!localVariables(
      local!testData: {
        {
          email: "hello@gmail.com",
          type: 1,
          date: today()
        },
        {
          email: "hello11@gmail.com",
          type: 1,
          date: today()
        },
        {
          email: "hello@gmail.com",
          type: 2,
          date: today()
        }
      },
      local!uniqueEmails: union(
        touniformstring(local!testData.email),
        touniformstring({})
      ),
      a!forEach(
        items: local!uniqueEmails,
        expression: index(
          index(
            local!testData,
            wherecontains(
              tostring(fv!item),
              touniformstring(index(local!testData, "email", {}))
            ),
            {}
          ),
          1,
          {}
        )
      )
    )

    9 replies

    stefanhelzle0001
    Brainy
    Jan 5, 2024 4:01 PM UTC

    I'd try to extract the email values from all items and then use the union() function to reduce duplicates.

    union(local!data.email, local!data.email)

    walkersAuthor
    Known Participant
    Jan 5, 2024 4:04 PM UTC

    That would return a list of unique email values, but not the list of cdt. What would be the best way to return the list of cdt where any duplicates on the email field have been removed?

    Inspiring
    Jan 5, 2024 4:11 PM UTC

    Hi,
    Following Stefan's suggestion, I have employed the 'unique' function and 'forEach' loop to retrieve the CDTs. Please refer to the code snippet below:

    a!localVariables(
      local!testData: {
        {
          email: "hello@gmail.com",
          type: 1,
          date: today()
        },
        {
          email: "hello11@gmail.com",
          type: 1,
          date: today()
        },
        {
          email: "hello@gmail.com",
          type: 2,
          date: today()
        }
      },
      local!uniqueEmails: union(
        touniformstring(local!testData.email),
        touniformstring({})
      ),
      a!forEach(
        items: local!uniqueEmails,
        expression: index(
          index(
            local!testData,
            wherecontains(
              tostring(fv!item),
              touniformstring(index(local!testData, "email", {}))
            ),
            {}
          ),
          1,
          {}
        )
      )
    )

    amans0009
    Participating Frequently
    Jan 5, 2024 5:31 PM UTC

    try this -> 

    a!localVariables(
      local!data: {
        'type!{urn:com:appian:types:DCT}DCT_temp'(
          type: 1,
          email: "212@gmail.com",
          date: today()
        ),
        'type!{urn:com:appian:types:DCT}DCT_temp'(
          type: 2,
          email: "211@gmail.com",
          date: today()
        ),
        'type!{urn:com:appian:types:DCT}DCT_temp'(
          type: 3,
          email: "212@gmail.com",
          date: today()
        ),
        'type!{urn:com:appian:types:DCT}DCT_temp'(
          type: 1,
          email: "213@gmail.com",
          date: today()
        )
      },
      local!descardDuplicateEmailValue: a!forEach(
        items: local!data,
        expression: index(
          local!data,
          index(
            /*find where else our current email resides*/
            wherecontains(fv!item.email, local!data.email),
            /*take only first one*/
            1,
            ""
          ),
          ""
        )
      ),
      union(
        local!descardDuplicateEmailValue,
        local!descardDuplicateEmailValue
      )
    )