2013-07-23 4 views
0

У меня есть JSON, который выглядит следующим образом (копируется из Dev инструментов инспектора)Упорядочивание объекта в JavaScript с помощью подчеркивания

salePurchases 
    salesPeriods: Array[2] 
    0: Object 
     data: Array[5] 
     0: Object 
     1: Object 
     2: Object 
     3: Object 
     4: Object 
     period: "2011" 
    1: Object 
     data: Array[5] 
     0: Object 
     1: Object 
     2: Object 
     3: Object 
     4: Object 
     period: "2012" 

    purchasePeriods: Array[2] 
    0: Object 
     data: Array[5] 
     0: Object 
     1: Object 
     2: Object 
     3: Object 
     4: Object 
     period: "2011" 
    2: Object 
     data: Array[5] 
     0: Object 
     1: Object 
     2: Object 
     3: Object 
     4: Object 
     period: "2012" 

Я хочу, чтобы вытащить его на части и сделать его создающим новый объект, который выглядит следующим образом -

OrderedByYears: 
    2011: 
    data: Array[10] 
     0: Object // this should be the 1st item from the salesPeriods array with a period of 2011 
     1: Object // this should be the 1st item from the purchasePeriods array with a period of 2011 
     2: Object 
     3: Object 
     4: Object 
     5: Object 
     6: Object 
     7: Object 
     8: Object 
     9: Object // this should be the 5th item from the salesPeriods array with a period of 2011 
     10: Object // this should be the 5th item from the purchasePeriods array with a period of 2011 
    2012: 
    data: Array[10] 
     0: Object // this should be the 1st item from the salesPeriods array with a period of 2012 
     1: Object // this should be the 1st item from the purchasePeriods array with a period of 2012 
     2: Object 
     3: Object 
     4: Object 
     5: Object 
     6: Object 
     7: Object 
     8: Object 
     9: Object // this should be the 5th item from the salesPeriods array with a period of 2012 
     10: Object // this should be the 5th item from the purchasePeriods array with a period of 2012 

Я основываю устройство на ключевом «периоде», а затем чередуюся между объединением каждого массива, но чередуя между продаваемыми объектами продаж и периодами покупки.

Я уверен, что это относительно просто с использованием подчеркивания. Кто-нибудь знает, если это легко сделать? Объяснение предпринятых шагов было бы высоко оценено.

+0

Предполагая, что вы застряли, и это не просто вопрос «напишите этот код для меня» - где вы застряли? –

+0

Я застрял на подходе, который я должен взять, я сейчас попробую ответить на ответ Джона. – Finnnn

ответ

0

Я не использовал underscore.js, но похоже, что он хорошо сочетается с общими понятиями. Вот общий подход, который вам нужен:

  1. concat salesPeriods and purchasePeriods вместе в один список.
  2. groupByperiod ценность в каждом из объектов.
  3. map сгруппированные результаты в форму объекта, которую вы хотите.

Возможно, вы захотите бросить там sort заявления в зависимости от ваших целей.

+0

Удивительно, спасибо большое.Я думаю, что я достиг того, чего хотел, без необходимости сопоставления. Извините мое невежество, но каковы преимущества картографии> – Finnnn

+0

@Finnnn: Позаботьтесь, чтобы поделиться своим решением? –

+0

@Finnnn: Сопоставление - всего лишь распространенный метод реструктуризации объекта. Иногда вы можете использовать другие методы для изменения объектов, но это скорее побочный эффект, чем фактический смысл функции. Итак, я перечислил карту, чтобы сделать процесс понятным. –

2

Я знаю, что у вас есть подход, который работает на вас. Я работал на Functional Programming Library в Javascript, и это, как я хотел бы справиться с этой проблемой с этой библиотекой:

var weave = compose(flatten, zip); 
reduce(function(obj, period) { 
    obj[period.year] = {data: period.data}; 
    return obj; 
}, {}, map(function(year) { 
    var getMatch = find(function(period) {return period.period === year;}); 
    return {year: year, data: weave(getMatch(salePurchases.salesPeriods).data, 
            getMatch(salePurchases.purchasePeriods).data)}; 
}, pluck("period", salePurchases.salesPeriods))); 

Эквиваленты для всех основных функций, используемых также доступны в Underscore, хотя в большинстве случаев порядок параметров отличается. Так с Underscore вы могли бы сделать это следующим образом:

var weave = _.compose(_.flatten, _.zip); 
_.reduce(_.map(_.pluck(salePurchases.salesPeriods, "period"), function(year) { 
    var getMatch = function(period) {return period.period === year;} 
    return {year: year, data: weave(_.find(salePurchases.salesPeriods, getMatch).data, 
            _.find(salePurchases.purchasePeriods, getMatch).data)}; 
}), function(obj, period) { 
    obj[period.year] = {data: period.data}; 
    return obj; 
}, {}); 

Вы можете увидеть это в действии с Ramda или Underscore на JSFiddle.

Основная идея заключается в том, что я бы начал со списка лет, вырвав продажиПериодов. (Предполагается, что ваши данные являются репрезентативными, и все годы должны появляться в обоих списках, а также то, что периоды продаж и периоды покупки являются всеобъемлющими.) Затем, используя map, я бы сплел период продаж и периоды покупки за каждый год , возвращая объект с годом и массив смежных данных. Чтобы превратить это в ваш ожидаемый результат, я бы присвоил reduce этот список, присвоив соответствующее свойство года новому объекту объекту, чье свойство data было тем, что смешало данные.

Этот метод позволяет провести небольшую проверку ошибок по пути, но довольно компактен.