2013-07-02 2 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 (то же самое для других с различной комбинацией): Первой комбинации для отеля с идентификатором 1:

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

Второй комбинацией для отеля с идентификатором 1:

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

каждого отель может иметь больше номеров какой-то уровня, но я хочу, чтобы построить комбинацию с одной комнатой Еогеасп отелем.

Это мой синтаксический анализ в позвоночнике, но я только извлекаю JSON внутри allRooms.

//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

Основываясь на ответе @ Берги, я придумал это. Он должен решить вашу проблему.

Вот демо: http://plnkr.co/edit/NHE9V5?p=preview

Обновлено Я изменил некоторые вещи, чтобы разместить свои отдельные файлы в формате JSON.

декартовой Helper продукт (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 для фиксации моего кода и его интеграции в базовую. Я бы лучше посмотрел на свою собственную «декартовую» функцию, я забыл, что она не берет массивы (или, по крайней мере, необходимо адаптировать). – 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

Проблема forst в группе, потому что верните мне массив с: add, after ... why? –

Смежные вопросы