使用下划线在javascript中重新排序对象

时间:2013-07-23 17:13:59

标签: javascript json underscore.js

我的json看起来像这样(从开发工具检查器复制)

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

我基于关键'句号'进行排列,然后在将每个数组连接在一起但在相关对象salesPeriods和purchasePeriods之间交替进行交替。

我确信使用下划线相对简单。任何人都知道这是一件容易的事吗?解释所涉及的步骤将非常感激。

2 个答案:

答案 0 :(得分:2)

我知道你有一种适合你的方法。我一直在使用Javascript中的 Functional Programming Library ,这就是我将如何处理该库的问题:

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;
}, {});

您可以在JSFiddle上使用 Ramda Underscore 查看此操作。

主要的想法是,我将从一个年份列表开始,从salesPeriods中剔除。 (这假设您的数据具有代表性,所需的所有年份都会显示在两个列表中,并且销售期和购买期都是全面的。)然后,使用map,我会将salesPeriod编织在一起并购买每年的时段,返回一年的对象,以及一系列混合数据。要将此转换为您的预期输出,我将reduce此列表,方法是将新对象的相关年份属性分配给data属性为混合数据的对象。

这种技术允许在此过程中进行少量错误检查,但非常紧凑。

答案 1 :(得分:0)

我没有使用underscore.js,但它看起来很好地映射到一般概念。以下是您想要的一般方法:

  1. concat将salesPeriods和purchasePeriods合并为一个列表。
  2. groupBy每个对象中的period值。
  3. map将分组的结果转换为您想要的对象形状。
  4. 您可能希望在其中添加一些sort语句,具体取决于您的目标。