2013-09-21 3 views
0

Я потянув меня за волосы с этим один - у меня есть следующий массив, продолжая объект - который содержит массив ваучеры (содержащие возможное бесконечное число объектов)Underscore.js фильтрация массива

var retailer = [ { _id: 52000c, 
    address: 'bla bla bla', 
    email: '[email protected]', 
    img: 'http://bla.jpg', 
    intro: ' hello', 
    strapLine: 'goodbye', 
    tel: '0000 0000000', 
    title: 'YE OLDE SHOPPE', 
    website: 'http://', 
    vouchers: 
    [ { _id: 523d003, 
     barcode: false, 
     description: 'blah', 
     endTime: '20 December 2013', 
     hidden: true, 
     redemptionCode: 'redemptionCode', 
     smallPrint: 'blah.', 
     startTime: 'Today', 
     title: 'blahbla' }, 
     { _id: 523de3, 
     barcode: false, 
     description: 'blah', 
     endTime: '20 December 2013', 
     hidden: true, 
     redemptionCode: 'redemptionCode', 
     smallPrint: 'blah.', 
     startTime: 'Today', 
     title: 'blahbla' }, 
     { _id: 523dr, 
     barcode: false, 
     description: 'blah', 
     endTime: '20 December 2013', 
     hidden: false, 
     redemptionCode: 'redemptionCode', 
     smallPrint: 'blah.', 
     startTime: 'Today', 
     title: 'blahbla' } ] 
} ] 

Использование underscore.js, я пытаюсь отфильтровать те ваучерные объекты с помощью свойства hidden (hidden == true), поэтому я получаю следующее: я получаю только те ваучеры, которые видны (скрыты == false)

var retailer = [ { _id: 52000c, 
     address: 'bla bla bla', 
     email: '[email protected]', 
     img: 'http://bla.jpg', 
     intro: ' hello', 
     strapLine: 'goodbye', 
     tel: '0000 0000000', 
     title: 'YE OLDE SHOPPE', 
     website: 'http://', 
     vouchers: 
     [{ _id: 523dr, 
      barcode: false, 
      description: 'blah', 
      endTime: '20 December 2013', 
      hidden: false, 
      redemptionCode: 'redemptionCode', 
      smallPrint: 'blah.', 
      startTime: 'Today', 
      title: 'blahbla' }] 
    } ] 

Так что, используя знак подчеркивания js, я написал следующее ba СЭД на предыдущем переполнение стека потока (Filtering array with underscore.js)

var visibleVouchers = _(retailer[0].vouchers).filter(function (x) { return !x.hidden;}); 

И это возвращает все видимые ваучеры - однако, я теряю ритейлер в этом процессе. Какой был бы лучший способ сделать это? Я пробовал много разных вещей, т. Е. Пытался заменить старый массив ваучеров новым, но он, похоже, не работает.

Спасибо, Роб

ответ

2

Использование _.map() на розничной торговле, что отображение взаимно однозначно. Внутри обратного вызова (каждый элемент розничного продавца) отфильтруйте ваучеры с использованием _.filter() (или _.reject(), в зависимости от вашего чувства).

var arrRetailers = _.map(retailers, function(retailer) { 
    var item = _.extend({}, retailer); 
    item.vouchers = _.filter(retailer.vouchers, function(voucher) { 
    return !voucher.hidden; 
    }) || []; //in case of there is no "visible" voucher 
    return item; 
}); 

Это возвращает новый массив и не меняет первоначальный массив розничных продавцов.

Если вы предпочитаете _.reject(), ваш обратный вызов должен быть адаптирован соответствующим образом:

_.reject(retailer.vouchers, function(voucher) { 
    return voucher.hidden; //note there is no exclamation mark 
}) || []; 

Надеется, что это помогает!

+1

Awesome - так это сохраняет оригинальность и создает новое со всем, что мне нужно. Благодаря :) – Rob

0

Я нашел сообщение в блоге http://www.untitleddesigns.com/2011/javascript-replace-array-contents/, который, кажется, отвечает на мой вопрос - он действительно работает, хотя я не знаком с прототипами - так что не совсем понимаю, почему его работа.

var visibleVouchers = _(retailer[0].vouchers).filter(function (x) { return !x.hidden;}); 
retailer[0].vouchers.length = 0; 
Array.prototype.push.apply(retailer[0].vouchers, visibleVouchers); 
Смежные вопросы