2013-07-02 94 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,因爲返回我的數組:添加,後...爲什麼? –