简体   繁体   中英

How do you merge two different arrays of objects of the same size?

I'm attempting to merge the following two objects into one. I want it to be an array of objects with values {companyType, companyName, companyLocation, companyPhone, score} but everything I've tried doesn't merge the objects properly. The actual objects are much larger but they are the same exact size. So I need something that deals with many objects in an array not just two items per array.

let company_details = [{companyType: 'Carrier',
                        companyName: 'Auto',
                        companyLocation: 'San Diego, CA',
                        companyPhone: '(123) 456-7890' },
                       {companyType: 'Dealer',
                        companyName: 'Car',
                        companyLocation: 'Indianapolis, IN',
                        companyPhone: '(234) 567-8901' }]

let scoreArr= [{score: 'Your Rating: None'},
               {score: 'Your Rating: Positive'}]

This approach takes an array of same length arrays and merge the objects at every index.

Methods used:

  • Array#reduce for reducing a set of arrays and getting a single array.

  • Array#map for mapping objects with an object from the left side of reduce a and an object from the right side of reduce b at the same index.

  • spread syntax ... for cloning an object as object literal. The order defines the value of same named properties, the last winns.

The result is an array of objects.

 let companies = [{ companyType: 'Carrier', companyName: 'Auto', companyLocation: 'San Diego, CA', companyPhone: '(123) 456-7890' }, { companyType: 'Dealer', companyName: 'Car', companyLocation: 'Indianapolis, IN', companyPhone: '(234) 567-8901' }], scores = [{ score: 'Your Rating: None' }, { score: 'Your Rating: Positive' }], merged = [companies, scores].reduce((a, b) => a.map((o, i) => ({ ...o, ...b[i] }))); console.log(merged);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

Some functional languages have very good list comprehension tools, for instance Haskell's zipWith. It takes two lists and applies a bivariate function to each set of elements.

However, we can easily implement it with arrow functions in present JS (ES6):

const zipWith = f => xs => ys => xs.map((x, i) => f(x, ys[i]));

In case you are not used to arrow function syntax: zipWith is a function with three parameters, a function f , and arrays xs and ys .

We use then map , a built in method of Array. It takes a function as argument and applies each element of xs to it. Hence the second arrow function in the argument of map. When map receives a bivariate function, it provides the array index corresponding to each element as second argument, here i .

We provide now x an element of xs as first argument to our provided function f . The second argument is the corresponding element of the other array ys[i] .

With the zipWith function we need another function to merge those objects in your array. The Object.assign method helps here:

const mergerFun = (a, b) => Object.assign({}, a, b)

Now apply it to your arrays:

const result = zipWith(mergerFun)(company_details)(scoreArr);

Here is it all in a snippet you can run. I've trimmed your objects to make the snippet a bit clearer.

 const companyDetails = [ { type: 'Carrier', name: 'Auto', }, { type: 'Dealer', name: 'Car', }, ]; const scoreArr = [ { score: 'None' }, { score: 'Positive' }, ]; // zipWith :: ( a -> b -> c ) -> [a] -> [b] -> [c] const zipWith = f => xs => ys => xs.map((x, i) => f(x, ys[i])); // mergerFun :: a -> b -> c const mergerFun = (a, b) => Object.assign({}, a, b); // put it all together const result = zipWith(mergerFun)(companyDetails)(scoreArr); console.log(result);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM