Given the following data structure:
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"}
]
I'm trying to sort and group it into these conditions:
What I have so far:
// 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 )
Ignore for a moment the fact that I've not got to the point where I can sort by date yet :)
The problem with the above seems to be that sortByStatus is being passed the IndexedIterable that is the overall group but not it's key so I can't sort it by that key. I think I probably need to use sortBy but the Immutable.js docs are incomprehensible and have no examples on which to work out how to achieve this.
So, the question: how can I take the result of the groupBy action and sort it into a custom order and additionally how can I ensure that all the items in each group are sorted by date?
Both, sort and reverse , are mutable in nature.
js provides many Persistent Immutable data structures including: List , Stack , Map , OrderedMap , Set , OrderedSet and Record .
it creates a Map, with only key a , which's value is plain object {b: {c: "banana"}} , and calling a map.
tojs lets you convert files between plain text, javascript strings, and document. write() statements. It's original purpose, was to read in an . html file, and output it as a series of document.
One easy fix is to just reach in to the first item of the array and get the status from there:
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())
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.1/immutable.js"></script>
I think you were almost there. The important thing to notice is that .groupBy
is returning a collection of lists, so when you call sort on that, you need a comparator that compares two different lists rather than two items. You can do this easily by just comparing the status of the first item in each list. After that, you want to sort each list individually by date, so you use .map
to apply a change to each list in your list, then .sortBy
on that list to sort by a specific key. Assuming you are using the built in Date type, 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, ... } ] ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With