Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I union/merge two Collections by their 'id' using UnderscoreJS

I have two collections (Menu and Orders)

Menu collection contains array of Item objects

[{'id': '1', 'name': 'apple'}, {'id': '2', 'name': 'orange'}]

And Orders collection also contains array of Item objects

[{'id': '1', 'quantity': '0'}]

And I want them merged together their attributes by ID into another collection (this is needed for templating purposes only):

[{'id': '1', 'name': 'apple', 'quantity': '1'}, {'id': '2', 'name': 'orange'}]

Is there a underscore method on this or I need to define a function for this? [it seems i tried all merging functions on underscore but none of them works the way I expected]

like image 685
user1076813 Avatar asked Dec 11 '22 15:12

user1076813


2 Answers

Don't think there is a function defined in underscore.js for this but one way to do it is by using the _.map and _.find functions as follows,

var menus = [{'id': '1', 'name': 'apple'}, {'id': '2', 'name': 'orange'}];

var orders = [{'id': '1', 'quantity': '0'}];

var newMenu = _.map(menus, function (menu) {  
    var order = _.find(orders, function (o) { 
        return o.id == menu.id;
    }); 
    return _.extend(menu, order); 
});

console.log(newMenu);
like image 70
naiquevin Avatar answered Dec 28 '22 11:12

naiquevin


Assuming your collections are Backbone collections

var menus = new Backbone.Collection([
    {'id': '1', 'name': 'apple'}, 
    {'id': '2', 'name': 'orange'}
]);

var orders = new Backbone.Collection([{'id': '1', 'quantity': 1}]);

you can take advantage of the functions proxied on collections and of collection.get :

var merged = menus.map(function(menu) {
    var id = menu.get('id'),
        order = orders.get(id);

    if (!order) return menu.toJSON();

    return _.extend(menu.toJSON(), order.toJSON());
});

And a Fiddle to play with http://jsfiddle.net/bs6jN/

like image 34
nikoshr Avatar answered Dec 28 '22 10:12

nikoshr