Skip to main content
January 5, 2024
Solved

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

  • January 5, 2024
  • 9 replies
  • 0 views

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.

    Best answer by mathurambm639546

    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
    January 5, 2024

    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
    January 5, 2024

    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?

    January 5, 2024

    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
    January 5, 2024

    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
      )
    )