带骨干的递归函数jquery

我在骨干网上有一个应用程序,我想在Json里面找到一些记录并打印出来。

我的JSON是这样的:

[ { "id" : "r1", "hotel_id" : "1", "name" : "Single", "level" : "1" }, { "id" : "r1_1", "hotel_id" : "1", "name" : "Double", "level" : "2" }, { "id" : "r1_3", "hotel_id" : "1", "name" : "Double for single", "level" : "1" }, { "id" : "r1_4", "hotel_id" : "1", "name" : "Triple", "level" : "3" }, { "id" : "r2", "hotel_id" : "2", "name" : "Single", "level" : "1" }, { "id" : "r2_1", "hotel_id" : "2", "name" : "Triple", "level" : "1" } ] 

我希望将每个酒店的每个房间结合起来。 每个酒店可以有更多的房间组合,但独特的水平。 我的目标是为id = 1的酒店打印这样的东西(另一个用不同的组合相同):酒店的第一个组合,ID为1:

 Room "Single", "level" : "1" , "hotel_id" : "1" Room "Double", "level" : "2" , , "hotel_id" : "1" Room "Triple", "level" : "3" , , "hotel_id" : "1" 

id为1的酒店的第二个组合:

 Room "Double for single", "level" : "1" , "hotel_id" : "1" Room "Double", "level" : "2" , , "hotel_id" : "1" Room "Triple", "level" : "3" , , "hotel_id" : "1" 

每个酒店都可以有更多的房间,但我想与一个房间foreach酒店建立组合。

这是我在骨干网中的解析,但我只检索allRooms中的JSON。

 //each for all my hotel _.each(this.collection.models, function(hotel) { var rooms = new Array(); rooms.push(allRooms.where({hotel_id : hotel.id})); //this is where I have to construct my combination //this is the array for each combination hotel.get('rooms').push(rooms); }); 

如何构建这个组合?

根据@ Bergi的回答,我提出了这个问题。 它应该解决你的问题。

这是一个演示: http : //plnkr.co/edit/NHE9V5?p = preview

更新我已经修改了一些东西来容纳你单独的JSON文件。

笛卡尔产品助手http://en.wikipedia.org/wiki/Cartesian_product

 function cartesian(arg) { arg = arg || []; var r = [], max = arg.length - 1; function helper(arr, i) { for (var j = 0, l = arg[i].length; j < l; j++) { var a = arr.slice(0); // clone arr a.push(arg[i][j]); if (i == max) { r.push(a); } else helper(a, i + 1); } } if(arg.length > 0) helper([], 0); return r; } 

嵌套集合解决方案

 HotelModel = Backbone.Model.extend({ initialize: function() { // because initialize is called after parse _.defaults(this, { rooms: new RoomCollection() }); }, parse: function(response) { if (_.has(response, "rooms")) { this.rooms = new RoomCollection(response.rooms, { parse: true }); delete response.rooms; } return response; }, toJSON: function() { var json = _.clone(this.attributes); json.rooms = this.rooms.toJSON(); return json; }, addRoom: function(rooms, options) { return this.rooms.add(rooms, options); }, removeRoom: function(rooms, options) { return this.rooms.remove(rooms, options); }, createRoom: function(attributes, options) { return this.rooms.create(attributes, options); }, getCombinations: function() { return cartesian(_.values(this.rooms.groupBy('level'))); } }); RoomModel = Backbone.Model.extend({}); HotelCollection = Backbone.Collection.extend({ model: HotelModel, getAllCombinations: function(){ return this.map(function(hotel){ return _.extend(hotel.toJSON(), { combinations: hotel.getCombinations() }); }); } }); RoomCollection = Backbone.Collection.extend({ model: RoomModel, getRoomsByHotelId: function(hotelId) { return this.where({ hotelId: hotelId }); } }); 

加载单独的JSON

 var hotels = new HotelCollection([], { url: 'hotels.json' }); var rooms = new RoomCollection([], { url: 'rooms.json' }); hotels.fetch({ success: function() { rooms.fetch({ success: function() { hotels.each(function(hotel) { hotel.addRoom(rooms.getRoomsByHotelId(hotel.id)); }); // all done here var combos = hotels.getAllCombinations(); $(function() { $('body').append('
' + JSON.stringify(combos, null, 2) + '

'); }); } }); } });

hotels.json

 [{ "id": 1, "name": "Hotel One" }, { "id": 2, "name": "Hotel Two" }, { "id": 3, "name": "Hotel Three" }] 

rooms.json

 [{ "level": 1, "name": "Room A", "hotelId": 1 }, { "level": 1, "name": "Room B", "hotelId": 1 }, { "level": 2, "name": "Room A", "hotelId": 1 }, { "level": 2, "name": "Room B", "hotelId": 1 }, { "level": 1, "name": "Room A", "hotelId": 2 }, { "level": 1, "name": "Room B", "hotelId": 2 }, { "level": 2, "name": "Room A", "hotelId": 2 }, { "level": 2, "name": "Room B", "hotelId": 2 }, { "level": 1, "name": "Room A", "hotelId": 3 }, { "level": 1, "name": "Room B", "hotelId": 3 }, { "level": 1, "name": "Room C", "hotelId": 3 }] 

首先,您应按酒店和级别拆分房间列表:

 var rooms = _(allRooms.groupBy, "hotel_id"); for (var hotelid in rooms) rooms[hotelid] = _.groupBy(rooms[hotelid], "level"); 

您正在寻找的“组合”是级别的笛卡尔积 (对于每个酒店)。 例如,您可以使用此辅助函数 。 像这样用它:

 _.each(this.collection.models, function(hotel) { var levels = rooms[hotel.id]; var combinations = cartesian(_.values(levels)); // put them on the hotel });