Merging two arrays together in JavaScript

Within my possession are two arrays:

 var g= [ 
        { id: 36, name: 'AAA', goal: 'yes' },
        { id: 40, name: 'BBB', goal: 'yes' },
        { id: 39, name: 'JJJ', goal: 'yes' },
        { id: 27, name: 'CCC', goal: 'yes' }];

    var c= [ 
        { id: 36, color:"purple" },
        { id: 40, color:"purple" },
        { id: 100, color:"pink"} ];

I am seeking the following output (performing a left join based on 'id'):

    res = [{ id: 36, name: 'AAA', goal: 'yes' , color:"purple"}, { id: 40, name: 'BBB', goal: 'yes', color:"purple" }]

The current logic I have performs a merge, but now I am in need of a logic for a left join:

    function mergeBy(key, data) {
      return Array.from(data
          .reduce((m, o) => m.set(o[key], { ...m.get(o[key]), ...o }), new Map)
          .values()
      );
    }

Answer №1

Below are different join functions that you can choose from:

function* mergeArrays(array1, array2, key) {
    let index = new Map(array2.map(item => [key(item), item]));
    for (let item of array1) {
        let currentKey = key(item);
        if (index.has(currentKey))
            yield {...item, ...index.get(currentKey)};
    }
}

function* leftJoinArrays(array1, array2, key) {
    let index = new Map(array2.map(item => [key(item), item]));
    for (let item of array1) {
        let currentKey = key(item);
        yield index.has(currentKey) ? {...item, ...index.get(currentKey)} : item;
    }
}

function* rightJoinArrays(array1, array2, key) {
    let index = new Map(array1.map(item => [key(item), item]));
    for (let item of array2) {
        let currentKey = key(item);
        yield index.has(currentKey) ? {...index.get(currentKey), ...item} : item;
    }
}


//

var arrayA = [
    {id: 1, value: 'a1'},
    {id: 2, value: 'a2'},
    {id: 7, value: 'a3'},
    {id: 8, value: 'a4'}
];

var arrayB = [
    {id: 1, value: 'b1'},
    {id: 2, value: 'b2'},
    {id: 9, value: 'b3'}
];


console.log('MERGE:')
console.log(...mergeArrays(arrayA, arrayB, item => item.id))
console.log('LEFT JOIN')
console.log(...leftJoinArrays(arrayA, arrayB, item => item.id))
console.log('RIGHT JOIN')
console.log(...rightJoinArrays(arrayA, arrayB, item => item.id))

Answer №2

When it comes to achieving the desired outcome, a left join is not what you need. What you actually require is an inner join of g and c using id in order to combine their properties. The following code snippet accomplishes this:

var g= [ 
        { id: 36, name: 'AAA', goal: 'yes' },
        { id: 40, name: 'BBB', goal: 'yes' },
        { id: 39, name: 'JJJ', goal: 'yes' },
        { id: 27, name: 'CCC', goal: 'yes' }];

var c= [ 
        { id: 36, color:"purple" },
        { id: 40, color:"purple" },
        { id: 100, color:"pink"} ];
    
function mergeBy(key, dataL, dataR) {
  const rMap = dataR.reduce((m, o) => m.set(o[key], { ...m.get(o[key]), ...o }), new Map);
  
  return dataL.filter(x => rMap.get(x[key])).map(x => ({...x, ...rMap.get(x[key]) }));
}

console.log(mergeBy("id",g, c))

Answer №3

If you're looking to extract uncommon keys from different sets and then filter the merged results, here's a JavaScript function that can help:

const
    mergeCommon = (a, b, key) => {
        const aByKey = a.reduce((m, o) => m.set(o[key], o), new Map);

        return b.reduce((r, o) => {
            if (aByKey.has(o[key])) r.push({ ... aByKey.get(o[key]), ...o});
            return r;
        }, []);
    },
    g = [{ id: 36, name: 'AAA', goal: 'yes' , 'random': 27 }, { id: 40, name: 'BBB', goal: 'yes' }, { id: 39, name: 'JJJ', goal: 'yes' }, { id: 27, name: 'CCC', goal: 'yes' , lag: "23.3343" }],
    c = [{ id: 36, name: 'AAA', goal: 'yes', color:"purple" }, { id: 40, name: 'BBB', circle: 'yes', color:"purple" }, { id: 100, name: 'JJJ', circle: 'yes'}],
    result = mergeCommon(g, c, 'id');

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

Answer №4

Utilize the power of Maps to merge two arrays together. Check out the code snippet which demonstrates Left Join, Right Join, and Inner Join functionalities.

All three join operations have a time complexity of O(N).

const g = [
  { id: 36, name: 'AAA', goal: 'yes', random: 27 },
  { id: 40, name: 'BBB', goal: 'yes' },
  { id: 39, name: 'JJJ', goal: 'yes' },
  { id: 27, name: 'CCC', goal: 'yes', lag: '23.3343' },
];

const c = [
  { id: 36, name: 'AAA', goal: 'yes', color: 'purple' },
  { id: 40, name: 'BBB', circle: 'yes', color: 'purple' },
  { id: 100, name: 'JJJ', circle: 'yes' },
];

const gMap = new Map(g.map(o => [o.id, o]));
const cMap = new Map(c.map(o => [o.id, o]));

const leftJoin = g.reduce(
  (a, o) => (cMap.has(o.id) ? [...a, { ...o, ...cMap.get(o.id) }] : [...a, o]),
  []
);

const rightJoin = c.reduce(
  (a, o) => (gMap.has(o.id) ? [...a, { ...o, ...gMap.get(o.id) }] : [...a, o]),
  []
);

const innerJoin = g.reduce(
  (a, o) => (cMap.has(o.id) ? [...a, { ...o, ...cMap.get(o.id) }] : a),
  []
);

console.log("LEFT JOIN\n", leftJoin)
console.log("RIGHT JOIN\n", rightJoin)
console.log("INNER JOIN\n", innerJoin)

Answer №5

var x = [ 
    { id: 36, name: 'AAA', purpose: 'yes' , 'random':27},
    { id: 40, name: 'BBB', purpose: 'yes' },
    { id: 39, name: 'JJJ', purpose: 'yes' },
    { id: 27, name: 'CCC', purpose: 'yes' , lag: "23.3343"}
];

var y = [ 
    { id: 36, name: 'AAA', purpose: 'yes', color:"purple" },
    { id: 40, name: 'BBB', circle: 'yes', color:"purple" },
    { id: 100, name: 'JJJ', circle: 'yes'} 
];


const mergedArr = (arr1, arr2) => {
//Filter the arr2 and find the only matching elements from the first array
    const filteredArray = arr2.filter(({id}) => arr1.some(({id: arr1Id}) => arr1Id === id));
    //Loop through the filtered array and fetch the matching item from first and add obj from filtered array
    return filteredArray.map(obj => {
        return {
            ...arr1.find(({id}) => id === obj.id),
            ...obj
        }
    })
}    
console.log(mergedArr(x, y));
.as-console-wrapper { 
  max-height: 100% !important;
}

Answer №6

Here is a concise solution

 const games = [ 
        { id: 36, name: 'AAA', goal: 'yes' },
        { id: 40, name: 'BBB', goal: 'yes' },
        { id: 39, name: 'JJJ', goal: 'yes' },
        { id: 27, name: 'CCC', goal: 'yes' }];

    const colors = [ 
        { id: 36, color:"purple" },
        { id: 40, color:"purple" },
        { id: 100, color:"pink"} ];



const result = games.map(item => !!colors.find(elem => elem.id === item.id) && ({...item, ...colors.find(elem => elem.id === item.id)})).filter(Boolean);
console.log(result);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

utilizing parent scope in a jQuery function callback

Currently, I am facing an issue concerning a jQuery callback working on a variable that is outside of its scope. To illustrate this problem, consider the code snippet below: $('#myBtn').on('click', function(e) { var num = 1; / ...

Vue alert: Issue with rendering - TypeError: Unable to access property 'NomeStr' as it is undefined

I'm having trouble displaying the 'NameSrt' item array value in my template, and I keep encountering this issue: vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read property 'NomeStr' of undefined" The ...

Develop an array of arrays using jython to facilitate interoperability with Java code

Looking to create a Java array of arrays? So far, I've been successful in creating a one-dimensional array using jarray.zeros(10, Object) Now, my goal is to create an outer array with jarray.zeros(2, Array) However, when I attempted this, I enco ...

How can I retrieve the value of an HTML component when submitting a form?

In my ExpressJS application, I have two pages: home and user. In the home.js file, I create a form that navigates to the user.js page when submitted. While I am able to retrieve values from input components, I am facing issues with other components. How ca ...

How to display two elements side by side within a div using React

I have an array that looks like this: const arr = [1,2,3,4,5,6,7,8,9,10] I am looking to display the elements in pairs per line within two-dimensional divs. Here is what I have in mind: This represents the main React element: render() { return <di ...

Using Ajax to insert data into WordPress

Looking to incorporate data into the WordPress database using Ajax integration. functions.php function addDataToDB(){ global $wpdb, $count; $count = 25; $wpdb->insert( 'custom_table', array( 'slid ...

Having difficulty locating the login button on the webpage

I am attempting to log into a banking account using selenuim. After opening the webpage and locating the login element, I initially struggled to access it by its "name" or "id." Fortunately, I was able to successfully access it using driver.find_element_by ...

Using the Gmail API to retrieve the access token details by extracting the "code" parameter from the URL of a pop-up window

I am currently in the process of authenticating Gmail using OAuth2 for my web application. Upon receiving a URL from the server, the client opens a pop-up window with the following code: var win = window.open(data.google_oauth_url, `<h1>Gmail ...

Continue executing without stopping

After making 4 ajax calls, the script is supposed to halt if record number 123456 is found. However, this specific record may appear in all four ajax responses. Despite this expectation, the code fails to stop processing. var endPoint0 = ''; var ...

What is the best way to access the child component in React?

const navArr = [ { path: "/introduction", title: "회사소개", subTitle: [{ title: "summary" }, { title: "vision" }], }, ] {navArr.map((obj) => { return ( <NavItem> ...

Using JQuery, remove any duplicate items from one list box and populate another list box

I have two list boxes set up: the leftBox contains all available options, while the rightBox displays the selected options. I am already familiar with how to add and remove items from each list box using jquery. However, my current goal is to automatically ...

Retrieve the variable only once a response has been received from the POST request

Is there a way to update a variable in my component only after receiving a response from a POST request? Here is the code in component.ts: formSubmit() { this.sent = this.submitProvider.sendByPost(this.form); this.formSent = this.submitProvider.f ...

Do these two JavaScript statements behave the same under the principles of functional programming in a React environment?

Is there a rule in functional programming that states these two approaches are equivalent? When working on a React application, I initially passed a function as an attribute using the second version where the first parameter is also passed. Out of curiosi ...

What criteria should I consider when selecting a make for the createTheme components?

After reviewing the documentation for the createTheme component, I noticed examples with MuiButtonBase, MuiButton, and MuiSlider. However, when it comes to adding a button, it's simply called Button, not MuiButton. So, does this mean I just need to p ...

Is there a way to instruct npm to compile a module during installation using the dependencies of the parent project?

I am curious about how npm modules are built during installation. Let me give you an example: When I check the material-ui npm module sources on GitHub, I see the source files but no built files. However, when I look at my project's node_modules/mate ...

Why isn't the externally loaded JS file executing properly?

My javascript code functions properly when it's embedded within the HTML file. However, I encounter issues when I try to import it externally. The Google Developer Tools indicate that the file has been loaded successfully, but there seems to be no vis ...

Utilizing express-session and passport to initiate a new session for each request

Currently working on developing an e-commerce platform, both front and back-end. Using express and passport for a basic login/register system. The issue I'm facing is that every time a page with a request is accessed, a new session is created and stor ...

Dynamic font sizing in CSS allows text on a webpage to

I am working on creating a dynamic screen using AngularJS. Within this screen, there are objects with a specific size: .item { margin: auto; margin-bottom: 10px; width: 11vw; height: 11vw; text-overflow: ellipsis; overflow: hidden; } These i ...

Electron JS-powered app launcher for seamless application launching

Currently, I am working on a project to develop an application launcher using HTML, CSS, and JS with Electron JS. Each application is linked through an a href tag that directs users to the respective application path. If a normal link is used in the a hr ...

How can I pass a specific value, rather than the entire array, in a ReactJS dropdown menu?

I am facing a problem where the entire array is being passed as an argument when I call onchange after getting correct values in the dropdown. Instead of only receiving the selected value, e contains the whole array. Here is the code snippet that demonst ...