I think you want an inner join that is fairly simple to implement in JavaScript:
const innerJoin = (xs, ys, sel) => xs.reduce((zs, x) => ys.reduce((zs, y) => // cartesian product - all combinations zs.concat(sel(x, y) || []), // filter out the rows and columns you want zs), []);
For demonstration purposes, we will use the following dataset (thanks @AshokDamani):
const userProfiles = [ {id: 1, name: "Ashok"}, {id: 2, name: "Amit"}, {id: 3, name: "Rajeev"}, ]; const questions = [ {id: 1, text: "text1", createdBy: 2}, {id: 2, text: "text2", createdBy: 2}, {id: 3, text: "text3", createdBy: 1}, {id: 4, text: "text4", createdBy: 2}, {id: 5, text: "text5", createdBy: 3}, {id: 6, text: "text6", createdBy: 3}, ];
Here's how you use it:
const result = innerJoin(userProfiles, questions, ({id: uid, name}, {id, text, createdBy}) => createdBy === uid && {id, text, name});
In terms of SQL, it will look like:
SELECT questions.id, questions.text, userProfiles.name FROM userProfiles INNER JOIN questions ON questions.createdBy = userProfiles.id;
Putting it all together:
const innerJoin = (xs, ys, sel) => xs.reduce((zs, x) => ys.reduce((zs, y) =>
Edit: However, this is not the best solution. Since the above solution passes through the Potato product , it takes O(m Γ n) time to start. With a little change, we can get it to work at O(m + n) time - @pebbl find it first :
const equijoin = (xs, ys, primary, foreign, sel) => { const ix = xs.reduce((ix, row) => // loop through m items ix.set(row[primary], row), // populate index for primary table new Map); // create an index for primary table return ys.map(row => // loop through n items sel(ix.get(row[foreign]), // get corresponding row from primary row)); // select only the columns you need };
Now you can use it as follows:
const result = equijoin(userProfiles, questions, "id", "createdBy", ({name}, {id, text}) => ({id, text, name}));
Putting it all together:
const equijoin = (xs, ys, primary, foreign, sel) => { const ix = xs.reduce((ix, row) => ix.set(row[primary], row), new Map); return ys.map(row => sel(ix.get(row[foreign]), row)); }; const userProfiles = [ {id: 1, name: "Ashok"}, {id: 2, name: "Amit"}, {id: 3, name: "Rajeev"}, ]; const questions = [ {id: 1, text: "text1", createdBy: 2}, {id: 2, text: "text2", createdBy: 2}, {id: 3, text: "text3", createdBy: 1}, {id: 4, text: "text4", createdBy: 2}, {id: 5, text: "text5", createdBy: 3}, {id: 6, text: "text6", createdBy: 3}, ]; const result = equijoin(userProfiles, questions, "id", "createdBy", ({name}, {id, text}) => ({id, text, name})); console.log(result);