1

I have been looking a simple way to copy/insert/move properties in an object within an array to another object. I came up with a basic logic which does the job perfectly but am not satisfied with this. There has to be a better way, any help here?

var first =  [
    {
        "AGREE_EFF_DATE__0": "02-Aug-2018",
        "AGREE_TERM_DATE__0": "30-Apr-2021",
        "AGREE_IND__0": "P1",
        "P_DBAR_IND__0": "N",
        "AGREE_EFF_DATE__1": "01-May-2021",
        "AGREE_TERM_DATE__1": null,
        "AGREE_IND__1": "NP",
        "P_DBAR_IND__1": "N",
        "PROVIDER_SPECIALITY__0": "PSYCHOLOGY, CLINICAL",
        "PROVIDER_SPECIALITY_CODE__0": "CK"
    }
];
var second = [
    {
        "STATUS": "ACTIVE",
        "MEDICARE_NUMBER" : 12345
    }
];

for(let i = 0; i < second.length; i++) {
    
    var first_keys = Object.keys(first[i]);
    var first_values = Object.values(first[i]);
    
    for(let j = 0; j < first_keys.length; j++) {
        second[i][first_keys[j]] = first_values[j];
    }
}


console.log(second);

//Output-
[
  {
    STATUS: 'ACTIVE',
    MEDICARE_NUMBER: 12345,
    AGREE_EFF_DATE__0: '02-Aug-2018',
    AGREE_TERM_DATE__0: '30-Apr-2021',
    AGREE_IND__0: 'P1',
    P_DBAR_IND__0: 'N',
    AGREE_EFF_DATE__1: '01-May-2021',
    AGREE_TERM_DATE__1: null,
    AGREE_IND__1: 'NP',
    P_DBAR_IND__1: 'N',
    PROVIDER_SPECIALITY__0: 'PSYCHOLOGY, CLINICAL',
    PROVIDER_SPECIALITY_CODE__0: 'CK'
  }
]
0

2 Answers 2

1

When possible, you should prefer iteration to manually indexed loops. This means arr.map() or arr.forEach() or arr.reduce(), to name a few.

Also, You can use an object spread to easily merge objects together.

Putting those together, you can reduce this logic to:

const result = first.map((firstObj, i) => ({ ...firstObj, ...second[i] }))

Here we map() over all members of first, which returns a new array where each member is the result of the function. This function takes the array member as the first argument, and the index of that member as the second argument. Then we can use that index to find the corresponding item in the second array.

Then you just spread both objects into a new object to assemble the final result.

var first =  [
    { a: 1, b: 2 },
    { a: 4, b: 5 },
];
var second = [
    { c: 3 },
    { c: 6 },
];

const result = first.map((firstObj, i) => ({ ...firstObj, ...second[i] }))

console.log(result)

Which is all perfectly valid typescript as well.


NOTE: there is one difference between my code any yours. Your code modifies the objects in second. My code returns new objects and does not change the contents of second at all.

This is usually the better choice, but it depends on how you use this value and how data is expected to flow around your program.

Sign up to request clarification or add additional context in comments.

5 Comments

You didn't take into account the option that one of the arrays can be larger than the other. In this case, your code will throw an error.
You are correct. However, I don't have enough information to assume how that should be handled. First, is a possible situation for the source data? If it is, then what should the behaviour be? Throw an exception? Return incomplete objects? There is no generically applicable "correct" behavior here.
Yes, I agree that it's now enough information in the question. But still - this is a very common mistake. So you can just add something like that in your response to be safe: ...(second[i] || {})
But that may lead to downstream errors where those properties are expected to exist, but they do not. A crash at that point will be way harder to debug ("How is it possible this field is undefined?!") than a crash in this function would be. So I believe that if the two arrays are expected to be the same length, then you should let it crash here because it will be easier to diagnose the problem. All this is to say, it depends. And without more direction on intended behavior, simple solutions should win over complex ones.
In this case, its expected that the arrays would be of same size.
0

You need to be careful with iterating, because you can have different count of elements in first and second arrays. So the possible solution will be like this:

const first = [
    {
        "AGREE_EFF_DATE__0": "02-Aug-2018",
        "AGREE_TERM_DATE__0": "30-Apr-2021",
        "AGREE_IND__0": "P1",
        "P_DBAR_IND__0": "N",
        "AGREE_EFF_DATE__1": "01-May-2021",
        "AGREE_TERM_DATE__1": null,
        "AGREE_IND__1": "NP",
        "P_DBAR_IND__1": "N",
        "PROVIDER_SPECIALITY__0": "PSYCHOLOGY, CLINICAL",
        "PROVIDER_SPECIALITY_CODE__0": "CK"
    }
];
const second = [
    {
        "STATUS": "ACTIVE",
        "MEDICARE_NUMBER": 12345
    }
];

console.log(mergeAll(first, second));

function mergeAll(firstArray, secondArray) {
    const result = [];
    const minLength = firstArray.length < secondArray.length ? firstArray.length : secondArray.length;

    for (let i = 0; i < minLength; i++) {
        result.push({...firstArray[i], ...secondArray[i]});
    }

    return result;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.