Reputation: 589
I have a JSON Object (Array of Arrays) that I need to filter with a specific order:
order: ['Hors','TTC','Total général', 'verger', ' Tra']
data = [[" Tra", "100 - 149 ch", "Total"]
[" Tra", "150 - 199 ch", "150 - 159 ch"]
[" Tra", "150 - 199 ch", "160 - 169 ch"]
[" Tra", "500 - 999 ch", "Total"]
[" Tra", "Total", ""]
["Comparable", "", ""]
["Hors", "", ""]
["TTC", "", ""]
["Total général", "", ""]
["vergers", " 1 - 49 ch", "20 - 29 ch"]
["vergers", " 1 - 49 ch", "30 - 39 ch"]
["vergers", " 1 - 49 ch", "40 - 49 ch"]
["vergers", " 50 - 99 ch", "70 - 79 ch"]]
I tried to use sort() but I doesn't fit my needs and some string contains spaces:
data.sort(function (a, b) {
return data.sort((a,b) => order.indexOf(a) - order.indexOf(b)) ;
});
This solution doesn't get me what I need, but stille the same Object
Upvotes: 0
Views: 107
Reputation: 3669
It's not indexOf(a)
/ indexOf(b)
but indexOf(a[0])
/ indexOf(b[0])
because you want to compare the first element of each array, not the whole array.
const order = ['Hors','TTC','Total général', 'vergers', ' Tra'];
const data = [
[" Tra", "100 - 149 ch", "Total"],
[" Tra", "150 - 199 ch", "150 - 159 ch"],
[" Tra", "150 - 199 ch", "160 - 169 ch"],
[" Tra", "500 - 999 ch", "Total"],
[" Tra", "Total", ""],
["Comparable", "", ""],
["Hors", "", ""],
["TTC", "", ""],
["Total général", "", ""],
["vergers", " 1 - 49 ch", "20 - 29 ch"],
["vergers", " 1 - 49 ch", "30 - 39 ch"],
["vergers", " 1 - 49 ch", "40 - 49 ch"],
["vergers", " 50 - 99 ch", "70 - 79 ch"],
];
/* const weights = Object.fromEntries( */
/* order.map((k,i)=>[k,i]) */
/* ); */
/* console.log(weights); */
function sortByOrder(data, order) {
const weight = Object.fromEntries(
// Pre-cache indexOf(...)
order.map((k,i)=>[k,i])
);
return data.sort(
([a],[b])=>weight[a]-weight[b]
);
};
console.log(sortByOrder(data,order));
// [ [ 'Hors', '', '' ],
// [ 'TTC', '', '' ],
// [ 'Total général', '', '' ],
// [ 'vergers', ' 1 - 49 ch', '30 - 39 ch' ],
// [ 'vergers', ' 1 - 49 ch', '20 - 29 ch' ],
// [ 'Comparable', '', '' ],
// [ 'vergers', ' 50 - 99 ch', '70 - 79 ch' ],
// [ 'vergers', ' 1 - 49 ch', '40 - 49 ch' ],
// [ ' Tra', '150 - 199 ch', '150 - 159 ch' ],
// [ ' Tra', 'Total', '' ],
// [ ' Tra', '500 - 999 ch', 'Total' ],
// [ ' Tra', '150 - 199 ch', '160 - 169 ch' ],
// [ ' Tra', '100 - 149 ch', 'Total' ] ]
Upvotes: 0
Reputation: 4519
if you wan all your data returned but sorted like in the order array you could use filter like this
order= ['Hors','TTC','Total général', 'vergers', ' Tra']
const data = [ [" Tra", "100 - 149 ch", "Total"], [" Tra", "150 - 199 ch", "150 - 159 ch"], [" Tra", "150 - 199 ch", "160 - 169 ch"], [" Tra", "500 - 999 ch", "Total"], [" Tra", "Total", ""], ["Comparable", "", ""], ["Hors", "", ""], ["TTC", "", ""], ["Total général", "", ""], ["vergers", " 1 - 49 ch", "20 - 29 ch"], ["vergers", " 1 - 49 ch", "30 - 39 ch"], ["vergers", " 1 - 49 ch", "40 - 49 ch"], ["vergers", " 50 - 99 ch", "70 - 79 ch"] ]
function sort(order){
result=[]
order.forEach(el =>result.push(data.filter(o=>el==o[0])));
result.unshift(data.filter(o=>!order.some(y=>y==o[0])))
return result.flat()
}
console.log(sort(order))
if you want to filter and sort only the element from order array you can try this
order= ['Hors','TTC','Total général', 'vergers', ' Tra']
const data = [ [" Tra", "100 - 149 ch", "Total"], [" Tra", "150 - 199 ch", "150 - 159 ch"], [" Tra", "150 - 199 ch", "160 - 169 ch"], [" Tra", "500 - 999 ch", "Total"], [" Tra", "Total", ""], ["Comparable", "", ""], ["Hors", "", ""], ["TTC", "", ""], ["Total général", "", ""], ["vergers", " 1 - 49 ch", "20 - 29 ch"], ["vergers", " 1 - 49 ch", "30 - 39 ch"], ["vergers", " 1 - 49 ch", "40 - 49 ch"], ["vergers", " 50 - 99 ch", "70 - 79 ch"] ]
function sort(order){
result=[]
order.forEach(el =>result.push(data.filter(o=>el==o[0])));
return result.flat()
}
console.log(sort(order))
Upvotes: 1
Reputation: 3496
If you want to sort by the first element of each array this should work:
(I changed 'verger' to 'vergers'. I guess that was a typo)
var order = ['Hors','TTC','Total général', 'vergers', ' Tra']
var data = [
[" Tra", "100 - 149 ch", "Total"],
[" Tra", "150 - 199 ch", "150 - 159 ch"],
[" Tra", "150 - 199 ch", "160 - 169 ch"],
[" Tra", "500 - 999 ch", "Total"],
[" Tra", "Total", ""],
["Comparable", "", ""],
["Hors", "", ""],
["TTC", "", ""],
["Total général", "", ""],
["vergers", " 1 - 49 ch", "20 - 29 ch"],
["vergers", " 1 - 49 ch", "30 - 39 ch"],
["vergers", " 1 - 49 ch", "40 - 49 ch"],
["vergers", " 50 - 99 ch", "70 - 79 ch"]
];
data.sort((a,b) => order.indexOf(a[0]) - order.indexOf(b[0])) ;
console.log(data)
If you also want to filter out non-matching elements:
var order = ['Hors','TTC','Total général', 'vergers', ' Tra']
var data = [
[" Tra", "100 - 149 ch", "Total"],
[" Tra", "150 - 199 ch", "150 - 159 ch"],
[" Tra", "150 - 199 ch", "160 - 169 ch"],
[" Tra", "500 - 999 ch", "Total"],
[" Tra", "Total", ""],
["Comparable", "", ""],
["Hors", "", ""],
["TTC", "", ""],
["Total général", "", ""],
["vergers", " 1 - 49 ch", "20 - 29 ch"],
["vergers", " 1 - 49 ch", "30 - 39 ch"],
["vergers", " 1 - 49 ch", "40 - 49 ch"],
["vergers", " 50 - 99 ch", "70 - 79 ch"]
];
data = data
.filter(x => order.indexOf(x[0]) > -1)
.sort((a,b) => order.indexOf(a[0]) - order.indexOf(b[0]));
console.log(data)
Upvotes: 0
Reputation: 2966
const data = [
[" Tra", "100 - 149 ch", "Total"],
[" Tra", "150 - 199 ch", "150 - 159 ch"],
[" Tra", "150 - 199 ch", "160 - 169 ch"],
[" Tra", "500 - 999 ch", "Total"],
[" Tra", "Total", ""],
["Comparable", "", ""],
["Hors", "", ""],
["TTC", "", ""],
["Total général", "", ""],
["vergers", " 1 - 49 ch", "20 - 29 ch"],
["vergers", " 1 - 49 ch", "30 - 39 ch"],
["vergers", " 1 - 49 ch", "40 - 49 ch"],
["vergers", " 50 - 99 ch", "70 - 79 ch"]
]
function sequence(arr) {
return arr.filter(ele => ["Hors","TTC", "Total général"].some(val => val === ele[0]))
.concat(arr.filter(ele => ele[0] === "vergers"))
.concat(arr.filter(ele => ele[0] === " Tra"))
}
console.log(sequence(data));
Upvotes: 0