mochim
mochim

Reputation: 71

How to get data from different tables with same id but different column name in javascript

I have two arrays of object:

var user = [
  {id: 1, name: 'David'},
  {id: 2, name: 'John'},
  {id: 3, name: 'Matt'},
]

var data = [
  {id: 1, userId: 1, flower: 'Clover'},
  {id: 2, userId: 1, flower: 'Sakura'},
  {id: 3, userId: 2, flower: 'Rose'},
  {id: 4, userId: 3, flower: 'Sunflower'},
]

and the output:

var result = [
      {name: 'David', flower: 'Clover'},
      {name: 'David', flower: 'Sakura'},
      {name: 'Matt', flower: 'Sunflower'},
    ]

I still don't know how to join two tables with different name column for id. Did anyone know the simplest way to do that in javascript? Thanks before

Upvotes: 0

Views: 1111

Answers (4)

Patrick
Patrick

Reputation: 519

As long as you aren't too concerned with performance, I'd recommend using lodash and creating a map of user id to user record for readability.

const { keyBy } = require('lodash');

const user = [
  {id: 1, name: 'David'},
  {id: 2, name: 'John'},
  {id: 3, name: 'Matt'},
];

const data = [
  {id: 1, userId: 1, flower: 'Clover'},
  {id: 2, userId: 1, flower: 'Sakura'},
  {id: 3, userId: 2, flower: 'Rose'},
  {id: 4, userId: 3, flower: 'Sunflower'},
];

const userIdToUserMap = keyBy(user, 'id');

const result = data.map(dataItem => {
  return {
    name: userIdToUserMap[dataItem.userId].name,
    flower: dataItem.flower        
  };
});

Lodash keyBy reference: https://lodash.com/docs/4.17.15#keyBy

Javascript array .map() reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

If you prefer to avoid using lodash, you can create the userIdToUserMap as follows:

const userIdToUserMap = user.reduce((acc, cur) => {
  acc[cur.id] = cur;
  return acc;
}, {});

Javascript array .reduce() reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

Upvotes: 0

devdb
devdb

Reputation: 49

//Making an index of all users
var userIndex={};  user.forEach (el=>{ if (el && el.id)  userIndex[el.id] = el });
//Fill the result with each data entry
var result = [];  data.forEach (el=>{ if(el && el.userId && userIndex[el.userId])  result.push({ name:userIndex[el.userId].name, flower:el.flower }) });
//Check for results
result.forEach(el=>console.log(el));

Some additional verification is implemented here against a corrupted data and exceptions: what if an user element haven't an id? Or, if a data entry haven't a userId? That's why not so "clean".

Upvotes: 0

Bulaxy
Bulaxy

Reputation: 119

Multiple ways to do it as other suggested. This is another one

Edit: Little bit confused about your question, but from my understanding, should be


var result = data.map(dataObj=>{
    return {
        name:user.find(userObj=>{
            return userObj.id === dataObj.userId
        }).name,
        flower:dataObj.flower
    }
})
console.log(result)

You might want to clarify why

{ name:'John', flower:'Rose'}

is excluded.

But my code will include that in it. Like the result below

console.log(result)

[
  { name: 'David', flower: 'Clover' },
  { name: 'David', flower: 'Sakura' },
  { name: 'John', flower: 'Rose' },
  { name: 'Matt', flower: 'Sunflower' }
]

Upvotes: 1

astigmatik
astigmatik

Reputation: 154

var user = [
    {id: 1, name: 'David'},
    {id: 2, name: 'John'},
    {id: 3, name: 'Matt'}
];
var data = [
    {id: 1, userId: 1, flower: 'Clover'},
    {id: 2, userId: 1, flower: 'Sakura'},
    {id: 3, userId: 2, flower: 'Rose'},
    {id: 4, userId: 3, flower: 'Sunflower'}
];
var results = [];
for (var x = 0; x < user.length; x++) {
    for (var y = 0; y < data.length; y++) {
        if (data[y].userId == user[x].id) {
            var tmp = { name: user[x].name, flower: data[y].flower }
            results.push(tmp);
        }
    }
}
console.log(results);

This can probably be done using filter and map, but I could only think of this for loop.

Upvotes: 0

Related Questions