userHG
userHG

Reputation: 589

Reorder JS Object with specific order

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

Answers (4)

bitifet
bitifet

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

Sven.hig
Sven.hig

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

Đinh Carabus
Đinh Carabus

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

Pavlos Karalis
Pavlos Karalis

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

Related Questions