Search code examples
ecmascript-6arrow-functions

Combine 2 lists into one using map & arrow function


I have 2 lists and I want to combine them so that I can populate them into a list. I know this can be done using nested for loops but, I'm trying to avoid for loops because of the amount of data I'll have to loop on. I would like to achieve this using the arrow functions or anything else.

List One:

let fields = [
    {
        field: "Name",
        fieldType: "Text"
    },
    {
        field: "Active__c",
        fieldType: "Boolean"
    },
    {
        field: "Contact",
        fieldType: "Relationship"
    }
];

List Two:

let rows = [
    {
        contact: {
            Name: "Joe",
            Active__c: true,
            Contact: "SomeContact"
        }
    },
    {
        contact: {
            Name: "Rachel",
            Active__c: true
        }
    },
    {
        contact: {
            Name: "Ross",
            Active__c: true
        }
    },
    {
        contact: {
            Name: "Monica",
            Active__c: true
        }
    }
];

Current code:

let output = rows.map(row => ({
    id: row.Id,
    data: {
        value: fields.map(field => (row.contact[field.field])),
        field: fields.map(field => field.field)
    }
}));

The output of this code:

[
    {
        "data": {
            "value": [
                "Joe",
                true,
                "SomeContact"
            ],
            "field": [
                "Name",
                "Active__c",
                "Contact"
            ]
        }
    },
    {
        "data": {
            "value": [
                "Rachel",
                true,
                null
            ],
            "field": [
                "Name",
                "Active__c",
                "Contact"
            ]
        }
    },
    {
        "data": {
            "value": [
                "Ross",
                true,
                null
            ],
            "field": [
                "Name",
                "Active__c",
                "Contact"
            ]
        }
    },
    {
        "data": {
            "value": [
                "Monica",
                true,
                null
            ],
            "field": [
                "Name",
                "Active__c",
                "Contact"
            ]
        }
    }
]

Desired output:

[
    data : [
        [
            {
                field : "Name",
                type: "Text",
                value : "Joe"
            },
            {
                field : "Active__c",
                type: "Boolean",
                value : true
            },
            {
                field : "Contact",
                type: "Relationship",
                value : "SomeContact"
            }
        ],
        [
            {
                field : "Name",
                type: "Text",
                value : "Rachel"
            },
            {
                field : "Active__c",
                type: "Boolean",
                value : false
            },
            {
                field : "Contact",
                type: "Relationship",
                value : "SomeContact Two"
            }
        ],
        [
            ...
        ],
        [
            ...
        ]
    ]
]

How can I achieve this?


Solution

  • The data property is unique and it has to be defined inline creating an object (not an array as you have in your desired output). You have to map fields array to each element of rows and then fill each field data with the row data if they exist. Also, I can't see an Id field on any row object inside rows array. This code sets null if a field does not exists:

    let output = {
      data: rows.map(({ contact }) => 
        fields.map(({ field, fieldType: type }) => ({
          field,
          type,
          value: field in contact ? contact[field] : null // Set null if contact has no field
        }))
      )
    }
    

    Run this code snippet to see the results:

    let fields = [
      {
        field: "Name",
        fieldType: "Text"
      },
      {
        field: "Active__c",
        fieldType: "Boolean"
      },
      {
        field: "Contact",
        fieldType: "Relationship"
      }
    ];
    
    let rows = [
      {
        contact: {
          Name: "Joe",
          Active__c: true,
          Contact: "SomeContact"
        }
      },
      {
        contact: {
          Name: "Rachel",
          Active__c: true
        }
      },
      {
        contact: {
          Name: "Ross",
          Active__c: true
        }
      },
      {
        contact: {
          Name: "Monica",
          Active__c: true
        }
      }
    ];
    
    let output = {
      data: rows.map(({ contact }) => 
        fields.map(({ field, fieldType: type }) => ({
          field,
          type,
          value: field in contact ? contact[field] : null
        }))
      )
    }
    
    document.getElementById('output').appendChild(
      document.createTextNode(JSON.stringify(output, null, 2))
    );
    <pre id="output"></pre>