2013-07-02 62 views
0

我有一个骨干应用程序,我想在Json里面找到一些记录并打印出来。与骨干网递归函数jQuery的

我的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); 
}); 

如何构建这种组合?

回答

3

基于@ 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('<pre>' + JSON.stringify(combos, null, 2) + '</pre>'); 
       }); 
      } 
     }); 
    } 
}); 

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 
}] 
+0

是的,如果你可以把它放在骨干网上就更好,如果你可以进入你的浏览器就可以试试它 –

+0

完成!哇,真是一个棘手的问题。 –

+0

+1用于修复我的代码并将其集成到Backbone中。我应该更好地看待自己的“笛卡儿”功能,我忘记了它不需要阵列(或者至少需要适应)。 – Bergi

1

首先,你应该通过酒店和水平分割你的房间列表:

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

的“组合”你要找的是水平(每家酒店)的cartesian product。例如,您可以使用this helper function。像这样使用它:

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

好吧,我有懂一点点,我见过的功能做到这一点。你能否用完整的代码(没有helpeer功能)完成答案?有可能吗?谢谢 –

+0

如果我把你的代码,我有一些问题,为此,我需要“完整”的解决方案 –

+0

最糟糕的问题是在groupby,因为返回我的数组:添加,后...为什么? –