2

As an example

I have two arrays

const tempData = [
          { day: "Mon", temp: 33.6 },
          { day: "Tue", temp: 34.6 },
          { day: "Wed", temp: 33.1 },
          { day: "Fri", temp: 35.6 }
        ];
const coughData = [
          { day: "Mon", count: 2 },
          { day: "Wed", count: 1 },
          { day: "Thur", count: 1 },
          { day: "Fri", count: 3 },
          { day: "Sat", count: 1 }
        ]; 

I need to merge these arrays into one so that if the day matches the count value adds to that object if it doesn't match it adds both objects to the array.

Don't know if the explanation isn't so clear but

The expected result should be like this:

const data = [
          { day: "Mon", temp: 33.6, count: 2 },
          { day: "Tue", temp: 34.6 },
          { day: "Wed", temp: 33.1, count: 1 },
          { day: "Thur", count: 1 },
          { day: "Fri", temp: 35.6, count: 3 },
          { day: "Sat", count: 1 }
        ];

I am trying to use map function like so but can't understand how do I return both the objects if they don't match:

const data = tempData.map(temp => {
          coughData.map(cough => {
            if (temp.day === cough.day) {
              return (temp.count = cough.count);
            } else {
              return cough;
            }
          });
          return temp;
        });
1
  • Array.map will transform array rows, it's name is map, So you have to use Array.reduce. Commented Dec 24, 2020 at 12:43

5 Answers 5

4

You could collect all data grouped by day in an object and get the values as result set.

const
    addToCollection = (collection, key) => o => Object.assign(collection[o[key]] ??= {}, o),
    tempData = [{ day: "Mon", temp: 33.6 }, { day: "Tue", temp: 34.6 }, { day: "Wed", temp: 33.1 }, { day: "Fri", temp: 35.6 }],
    coughData = [{ day: "Mon", count: 2 }, { day: "Wed", count: 1 }, { day: "Thur", count: 1 }, { day: "Fri", count: 3 }, { day: "Sat", count: 1 }],
    collection = {};
    
tempData.forEach(addToCollection(collection, 'day'));
coughData.forEach(addToCollection(collection, 'day'));

console.log(Object.values(collection));
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

Comments

2

You can first merge the objects of the arrays, and then use .reduce() along with a Map to accumulate the values. The Map can be keyed by the day property, which will allow you to group related object properties together. You can then use Array.from() to transform your Map back into an array of objects like so:

const tempData = [{ day: "Mon", temp: 33.6 }, { day: "Tue", temp: 34.6 }, { day: "Wed", temp: 33.1 }, { day: "Fri", temp: 35.6 }];
const coughData = [{ day: "Mon", count: 2 }, { day: "Wed", count: 1 }, { day: "Thur", count: 1 }, { day: "Fri", count: 3 }, { day: "Sat", count: 1 }];

const arr = [...tempData, ...coughData];

const result = Array.from(arr.reduce((map, {day, ...rest}) => {
  const seen = map.get(day) || {day};
  return map.set(day, {...seen, ...rest});
}, new Map).values());

console.log(result);

2 Comments

If you add a day key instead of empty object literal here: map.get(day) || { day }, you can get Array.from(mapFromReduce.values()). No need for the additional operation of ([day, obj]) => ({day, ...obj})
@adiga Nice, that's much nicer, thanks :D
0
let newArray = Array();
let longer = (tempData.length <= coughData.length) ? coughData.length : 
tempData.length;
for(let i = 0, j = 0; i < longer; ++i, ++j) {
    newArray.push(Object.assign(coughData[i], tempData[j]));
}

Print to console:

[ { day: 'Mon', count: 2, temp: 33.6 },
{ day: 'Tue', count: 1, temp: 34.6 },
{ day: 'Wed', count: 1, temp: 33.1 },
{ day: 'Fri', count: 3, temp: 35.6 },
{ day: 'Sat', count: 1 } ]

Comments

0

const tempData = [
    { day: "Mon", temp: 33.6 },
    { day: "Tue", temp: 34.6 },
    { day: "Wed", temp: 33.1 },
    { day: "Fri", temp: 35.6 }
];
const coughData = [
    { day: "Mon", count: 2 },
    { day: "Wed", count: 1 },
    { day: "Thur", count: 1 },
    { day: "Fri", count: 3 },
    { day: "Sat", count: 1 }
];

const tempRes = [...tempData, ...coughData];
const result = tempRes.reduce((acc, curr) => {
    const { day, ...rest } = curr;
    acc[day] = acc[day] ? Object.assign({}, acc[day], rest) : curr
    return acc;
}, {})
console.log(Object.values(result))
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

-4

You can use Object.assign() javascript function. The Object.assign () method is used to copy the values ​​of all the enumerable properties of one or more source objects to a target object. This method will return the target object

Like so:

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };

const returnedTarget = Object.assign(target, source);

console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }

console.log(returnedTarget);
// expected output: Object { a: 1, b: 4, c: 5 }

https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

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.