对Immutable.js列表进行排序和分组

时间:2016-09-27 09:43:36

标签: javascript immutable.js

鉴于以下数据结构:

var MyData = [
  {"id": 1, "status": "live", dateCreated: "12:00:00 01/02/2016"}, 
  {"id": 2, "status": "draft", dateCreated: "13:00:00 03/12/2015"}, 
  {"id": 3, "status": "ready", dateCreated: "16:00:00 04/09/2016"}, 
  {"id": 4, "status": "ready", dateCreated: "10:00:00 01/10/2016"}, 
  {"id": 5, "status": "live", dateCreated: "09:00:00 05/07/2015"}, 
  {"id": 6, "status": "draft", dateCreated: "08:00:00 11/03/2016"}, 
  {"id": 7, "status": "ready", dateCreated: "20:00:00 12/02/2016"}
]

我正在尝试对它进行排序并将其分组到这些条件中:

  1. 按状态分组
  2. 按状态订购,订单为“现场”,“草稿”,“准备好”
  3. 每个状态中的项目应按dateCreated排序,最近一次。
  4. 到目前为止我所拥有的:

    // this object will help us define our custom order as it's not alphabetical
    const itemOrder = {
      'live': 1, 
      'ready': 2,
      'draft': 3
    };
    
    const sortByStatus = (statusA, statusB) => {
      if ( itemOrder[statusA] > itemOrder[statusB] ) return 1;
      if ( itemOrder[statusA] < itemOrder[statusB] ) return -1;
      return 0;
    };
    
    return List(MyData)
      .groupBy(item => item.status)
      .sort( sortByStatus )
    

    暂时忽略了这样一个事实:我还没有达到我可以按日期排序的程度:)

    上面的问题似乎是sortByStatus正在传递IndexedIterable,它是整个组但不是它的键,所以我不能用那个键对它进行排序。我认为我可能需要使用sortBy,但是Immutable.js文档是不可理解的,并且没有关于如何实现这一点的示例。

    所以,问题是:如何获取groupBy操作的结果并将其排序为自定义顺序,另外如何确保每个组中的所有项目按日期排序?

2 个答案:

答案 0 :(得分:1)

一个简单的解决方法是直接进入数组的第一项并从那里获取状态:

&#13;
&#13;
var MyData = [
  {"id": 1, "status": "live", dateCreated: "12:00:00 01/02/2016"}, 
  {"id": 2, "status": "draft", dateCreated: "13:00:00 03/12/2015"}, 
  {"id": 3, "status": "ready", dateCreated: "16:00:00 04/09/2016"}, 
  {"id": 4, "status": "ready", dateCreated: "10:00:00 01/10/2016"}, 
  {"id": 5, "status": "live", dateCreated: "09:00:00 05/07/2015"}, 
  {"id": 6, "status": "draft", dateCreated: "08:00:00 11/03/2016"}, 
  {"id": 7, "status": "ready", dateCreated: "20:00:00 12/02/2016"}
]

const itemOrder = {
  'live': 1, 
  'ready': 2,
  'draft': 3
};

const sortByStatus = (statusA, statusB) => {
var a = itemOrder[statusA.get(0).status];
var b = itemOrder[statusB.get(0).status];
console.log(statusA.get(0).status, a, statusB.get(0).status, b)
  if ( a > b ) return 1;
  if (a < b ) return -1;
  return 0;
};

var result = Immutable.List(MyData)
  .groupBy(item => item.status)
  .sort( sortByStatus );
  
  console.log(result.toJS())
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.1/immutable.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

我想你差不多了。需要注意的重要一点是.groupBy正在返回列表集合,因此当您对其进行排序时,需要一个比较器来比较两个不同的列表而不是两个项目。只需比较每个列表中第一项的状态,即可轻松完成此操作。之后,您希望按日期对每个列表进行单独排序,因此您可以使用.map对列表中的每个列表应用更改,然后在该列表上.sortBy按特定键排序。假设您使用的是内置Date类型,just sorting by that field should do what you want

var MyData = [
  {"id": 1, "status": "live", dateCreated: "12:00:00 01/02/2016"}, 
  {"id": 2, "status": "draft", dateCreated: "13:00:00 03/12/2015"}, 
  {"id": 3, "status": "ready", dateCreated: "16:00:00 04/09/2016"}, 
  {"id": 4, "status": "ready", dateCreated: "10:00:00 01/10/2016"}, 
  {"id": 5, "status": "live", dateCreated: "09:00:00 05/07/2015"}, 
  {"id": 6, "status": "draft", dateCreated: "08:00:00 11/03/2016"}, 
  {"id": 7, "status": "ready", dateCreated: "20:00:00 12/02/2016"}
]


Immutable.fromJs(MyData)
  // [{id: 1, ...}, ...]
  .groupBy(item => item.status) // group items into lists by status
  // [ 'live': [ { id: 1, ... }, { id:5, ... } ],
  //   'draft': [ { id: 2, ... }, { id: 6, ...} ],
  //   'ready': [ { id: 3, ... }, { id: 4, ... }, { id: 7, ... } ] ]
  .sort((listA, listB) => // order these groups by status
    itemOrder[listA.first().status] - itemOrder[listB.first().status])
  // [ 'live': [ { id: 1, ...}, ... ],
  //   'ready': [ { id: 3, ...}, ... ], 
  //   'draft': [ { id: 2, ...}, ... ] ]
  .map(list => list.sortBy(item => item.dateCreated)); // sort the elements in each group by date
  // [ 'live': [ { id: 5, ... }, { id: 1, ... } ],
  //   'ready': [ { id: 4, ... }, { id: 3, ... }, { id: 7, ... } ], 
  //   'draft': [ { id: 2, , ...}, { id: 6, ... } ] ]