Reputation: 1477
I am trying to sort an Array
using a String
field and it is sorting it wrongly.
My code looks like this.
let tempWEArray = [
{
"from" : "09/2005",
"to" : "11/2006"
},
{
"from" : "09/2006",
"to" : "11/2007"
},
{
"from" : "12/2007",
"to" : "01/2009"
},
{
"from" : "01/2009",
"to" : "12/2012"
},
{
"from" : "01/2013",
"to" : "03/2018"
}]
function sortBy(prop){
return function(a,b){
if( a[prop] < b[prop])
{
return -1;
}
else if( a[prop] > b[prop] )
{
return 1;
}
return 0;
}
}
console.log(tempWEArray.sort(sortBy("to")))
The output obtained is like below.
0: Object { from: "12/2007", to: "01/2009" }
1: Object { from: "01/2013", to: "03/2018" }
2: Object { from: "09/2005", to: "11/2006" }
3: Object { from: "09/2006", to: "11/2007" }
4: Object { from: "01/2009", to: "12/2012" }
The Array isn't getting sorted properly as you can see above. One field is misplaced. Am i doing something wrong?
All the below answers work, I've selected the Answer which I have implemented. Thanks everyone.
Upvotes: 1
Views: 218
Reputation: 89
function sortBy(prop) {
return function(a, b) {
const dateArray = b[prop].split("/").reverse()
console.log()
}
}
Upvotes: 2
Reputation: 17616
Convert it to a date in your sort and it'll work as you intended.
seperate each component of the date string and reverse it
const dateArray = b[prop].split("/").reverse()
Use the spread operator to create a timestamp with Date.UTC and then use new Date
to create a date.
new Date(Date.UTC(...dateArray))
Then use the -
between two dates to find which one is bigger in a sort function.
Some example:
const res = new Date(Date.UTC(..."11/2006".split("/").reverse()))
console.log(res);
Full solution:
let tempWEArray = [{"from":"09/2005","to":"11/2006"},{"from":"09/2006","to":"11/2007"},{"from":"12/2007","to": "01/2009"},{"from":"01/2009","to": "12/2012"},{"from":"01/2013","to": "03/2018"}]
function sortBy(prop) {
return function(a, b) {
const dateArr1 = a[prop].split("/").reverse();
const dateArr2 = b[prop].split("/").reverse();
//make sure months are between 0 and 11
//can be skipped if this is already ensured.
dateArr1[1]--;
dateArr2[1]--;
return new Date(Date.UTC(...dateArr2)) - new Date(Date.UTC(...dateArr1));
}
}
console.log(tempWEArray.sort(sortBy("to")))
Upvotes: 2
Reputation: 386624
You could replace the date pattern with a comparable string and omit if the string has not a date pattern.
function sortBy(prop){
return function(a,b){
var valueA = a[prop].replace(/^(\d{2})\/(\d{4})$/, '$2-$1'),
valueB = b[prop].replace(/^(\d{2})\/(\d{4})$/, '$2-$1');
return valueA.localeCompare(valueB);
}
}
var tempWEArray = [{ from: "09/2005", to: "11/2006" }, { from: "09/2006", to: "11/2007" }, { from: "12/2007", to: "01/2009" }, { from: "01/2009", to: "12/2012" }, { from: "01/2013", to: "03/2018" }]
console.log(tempWEArray.sort(sortBy("to")))
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 122047
You could first parse those dates and then you can use -
to sort them.
let arr = [{"from":"09/2005","to":"11/2006"},{"from":"09/2006","to":"11/2007"},{"from":"12/2007","to":"01/2009"},{"from":"01/2009","to":"12/2012"},{"from":"01/2013","to":"03/2018"}]
const parse = str => {
let date = new Date;
let [month, year] = str.split('/')
date.setYear(year);
date.setMonth(+month - 1)
return date;
}
const sortBy = prop => (a, b) => {
return parse(b[prop]) - parse(a[prop])
}
arr.sort(sortBy('to'))
console.log(arr)
Upvotes: 3
Reputation: 2502
You can use moment.js for date camparation. example:
let tempWEArray = [
{
"from" : "09/2005",
"to" : "11/2006"
},
{
"from" : "09/2006",
"to" : "11/2007"
},
{
"from" : "12/2007",
"to" : "01/2009"
},
{
"from" : "01/2009",
"to" : "12/2012"
},
{
"from" : "01/2013",
"to" : "03/2018"
}];
const sortedArray = tempWEArray.sort(
(first, second) => moment(first.to, 'MM/YYYY')
.isSameOrAfter(moment(second.to, 'MM/YYYY')));
console.log(sortedArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.23.0/moment.min.js"></script>
Upvotes: 2