Forum Discussion

alex_panganiban's avatar
alex_panganiban
Contributor
4 years ago
Solved

Counting Instances in Array Object and Removing Duplicates

As I process an array, I want to see if I have any duplicate names in the array that I am processing. If I encounter a duplicate name, I only want to keep the one where the series contains “Trekker.” How can I do this?

For example, given the shows array below. My goal is to remove the first instance of Spock and keep the instance that contains the word, Trekker.

shows: [
{ name: ‘James T. Kirk’, series: ‘Star Trek’ },
{ name: ‘Spock’, series: ‘Star Trek’, ‘Star Trek: The Next Generation’ },
{ name: ‘Jean-Luc Picard’, series: ‘Star Trek: The Next Generation’ },
{ name: ‘Worf’, series: ‘Star Trek: The Next Generation’ },
{ name: ‘Spock’, series: ‘Star Trek’, ‘Star Trekker’ }
]

I’ve been able to get rid of duplicate names using the following filter method, however, due to the positioning index, it always gets rid of the one I want to keep.

$shows.filter((show, pos, a) => a.findIndex(item => item.name == a[pos].name) == pos)

In this example, I got all 5 instances of the array back.

$shows.filter((show, pos, a) => a.findIndex(item => item.name == a[pos].name) != pos
&& a[pos].series.contains(“Trekker”)
|| a.findIndex(item => item.name == a[pos].name) == pos)

I thought if I could get the count of the current name, then I could leverage the count value to incorporate in the filters above, however, I can’t figure out how to do that.

$shows.filter(show => show.name == “Spock”).length

$shows.filter((show, pos, a) => a.findIndex(item => item.name == a[pos].name) != pos
&& a[pos].series.contains(“Trekker”)
|| a.findIndex(item => item.name == a[pos].name) == pos && COUNT == 1)

I also tried using the array.prototype.findLastIndex, but either SnapLogic didn’t like it or maybe it’s a Java/Javascript version issue.

Please help. My Javascript skills, especially when using callbacks, sucks. And thank you.

3 Replies

    • wpenfold's avatar
      wpenfold
      Contributor

      Does Snaplogic use StAXON conventions? I still can’t figure out how to use the Mapper to include both an attribute and value on a single XML node

      • dimitri_hristov's avatar
        dimitri_hristov
        Contributor

        I’ve put together a sample pipeline. In it I use a Mapper Snap to create the needed input for the XML Formatter Snap.

        XML_with_Mapper_2020_06_29.slp (6.8 KB)

        Hope it helps to clarify, or muddify 🙂 the matter further.

        BR,
        Dimitri

    • wpenfold's avatar
      wpenfold
      Contributor

      Thanks! Using the $ gave me the node value I needed.

  • Another question… If an email exists for the person, I need to create an xml node like this:

    <email_address>XXXX@xxx.edu</email_address>
    <email_types>
    <email_type>work</email_type>
    </email_types>
    < / email >

    But if we don’t have an email address, it needs to be just:

    < / email >

    Is there a way to do this in the mapper? I can handle one condition or the other, but not both. Do I have to use a router and 2 mappers?.. (I can’t get the end tags to show in this editor unless I add spaces)

    • dimitri_hristov's avatar
      dimitri_hristov
      Contributor

      Hi,

      Assuming that in the input document of the Mapper (where you want to produce the JSON Object to be formatted to valid XML) you have this kind of structure:
      {
      “email”: {
      “type”: “work”,
      “address”: “one@two.com
      }
      }
      then, if you put this into the Expression in the Mapper Snap:

      ($.hasPath("email") && $email != null) ? {}.extend( {email_address:$email.address, email_types:{email_type:$email.type } } ) : null

      and assign it to the $email Target Path, that should produce the intended results.

      Here’s a pipeline where the elaborated above is implemented:
      XML_with_Mapper_2_2020_07_02.slp (6.5 KB)

      BR,
      Dimitri