0

I have no idea how I can sort an array of objects comparing two keys. I have array:

const arr = [
  {
    age: "20",
    group: "XXX",
    id: "3L1aa1558002753379",
    menu: "standard",
    name: "Adam"
  },
  {
    age: "22",
    group: "XXX",
    id: "xhNt11558002753379",
    menu: "standard",
    name: "Ola"
  },
  {
    otherid: "3L1aa1558002753379",
    age: "25",
    group: "YYY",
    id: "6ryVK1558002753379",
    menu: "standard",
    name: "Wommman"
  },
  {
    otherid: "xhNt11558002753379",
    age: "25",
    group: "YYY",
    id: "aL1aa1558002753312",
    menu: "standard",
    name: "xxxxxy"
  },
  {
    age: "25",
    group: "YYY",
    id: "6ryVK1558002753379",
    menu: "standard",
    name: "xxxxxo"
  }
  ,
  {
    otherid: "1ryVK1558002753372",
    age: "25",
    group: "YYY",
    id: "9ryVK155a002753370",
    menu: "standard",
    name: "xxxxxo"
  },
  {
    age: "25",
    group: "YYY",
    id: "1ryVK1558002753372",
    menu: "standard",
    name: "xxxxxo"
  }
];

I want to sort in this way: if "id" and "otherid" is the same - let objects be next to each other. I do not know how to do it, would anyone be so good?

Like here:

    const arr = [
  {
    age: "20",
    group: "XXX",
    id: "3L1aa1558002753379",
    menu: "standard",
    name: "Adam"
  },
  {
    otherid: "3L1aa1558002753379",
    age: "25",
    group: "YYY",
    id: "6ryVK1558002753379",
    menu: "standard",
    name: "Wommman"
  },
  {
    age: "22",
    group: "XXX",
    id: "xhNt11558002753379",
    menu: "standard",
    name: "Ola"
  },
  {
    otherid: "xhNt11558002753379",
    age: "25",
    group: "YYY",
    id: "aL1aa1558002753312",
    menu: "standard",
    name: "xxxxxy"
  },
  {
    age: "25",
    group: "YYY",
    id: "1ryVK1558002753372",
    menu: "standard",
    name: "xxxxxo"
  },
  {
    otherid: "1ryVK1558002753372",
    age: "25",
    group: "YYY",
    id: "9ryVK155a002753370",
    menu: "standard",
    name: "xxxxxo"
  },
    {
    age: "25",
    group: "YYY",
    id: "6ryVK1558002753379",
    menu: "standard",
    name: "xxxxxo"
  }
  ,
];

I tried something similar to this: Javascript sort array by two fields but it failed

kml
  • 31
  • 1
  • 4

2 Answers2

0

You pointed out, that you only need to compute pairs and render them in a react application.

It would make much more sense to structure your data in a way your view can directly render it.

Since you are in control of the data, you don't need to generate a flat list. You can setup the pairs (of students, or whatever) using a hierarchical structure, or nested obejcts.

let students = [{name: 'Jon', id:0}, {name: 'Peter', id: 1}, {name: 'Steve', id:2}, {name: 'Joe', id: 3}]
let pairs = [{a: students [3], b: students[1]}, {a: students [2], b: students [0]}];
console.log (pairs);

Now if you want to render those pairs, you already have the data in the structure you need.

render () {
      return pairs.map (pair => <Pair data={pair} />)
}

You can also flatten the pairs array and render a flat list of elements next to each other if you prefer.

let students = [{name: 'Jon', id:0}, {name: 'Peter', id: 1}, {name: 'Steve', id:2}, {name: 'Joe', id: 3}]
let pairs = [{a: students [3], b: students[1]}, {a: students [0], b: students [2]}];
const flatten = (flat, {a, b}) => [...flat, a, b];
const sorted  = pairs.reduce (flatten, []);
console.log (sorted)
const Student = data => <div>{data.name}</div>
const Pair = pair => <div>
    <Student data={pair.a} />
    <Student data={pair.b} />
</div>
const renderFlat = () => {
     return sorted.map (student => <Student data={student} />
}
const renderPairs = () => {
     reutnr pairs.map (pair => <Pair data={pair} />)
}

I hope I make at least a bit sense. - Here is the sort function in any case

function sort (arr)  {
   let otherids = arr.reduce ((lkp, obj) => {
       if (obj.otherid)
       lkp [obj.otherid] = obj;
       return lkp;
   }, {}); 

   let sorted = []; 

   for (var i=0; i < arr.length; i++) {
      let obj = arr [i];
      if (!!~sorted.indexOf (obj)) continue;
      
      if (otherids [obj.id]) {
          sorted.push (obj) 
          sorted.push(otherids[obj.id])
      }
   }

   return sorted.concat (arr.filter (obj => !~sorted.indexOf (obj)));
}

let sorted = sort (arr);
console.log (sorted);
<script>var arr=[{age:"20",group:"XXX",id:"3L1aa1558002753379",menu:"standard",name:"Adam"},{age:"22",group:"XXX",id:"xhNt11558002753379",menu:"standard",name:"Ola"},{otherid:"3L1aa1558002753379",age:"25",group:"YYY",id:"6ryVK1558002753379",menu:"standard",name:"Wommman"},{otherid:"xhNt11558002753379",age:"25",group:"YYY",id:"aL1aa1558002753312",menu:"standard",name:"xxxxxy"},{age:"25",group:"YYY",id:"6ryVK1558002753379",menu:"standard",name:"xxxxxo"},{otherid:"1ryVK1558002753372",age:"25",group:"YYY",id:"9ryVK155a002753370",
menu:"standard",name:"xxxxxo"},{age:"25",group:"YYY",id:"1ryVK1558002753372",menu:"standard",name:"xxxxxo"}];</script>
Moritz Roessler
  • 8,542
  • 26
  • 51
  • 1
    It works! You're wonderful! Beer for you: D I'm a beginner at React. I need this to do just such couples, I do not know if this is a good idea, but only this solution came to my mind. – kml May 16 '19 at 14:22
  • :) Glad I could help, if you only want to do pairs, i would suggest keeping an array of pairs `[[{a: {...}, b: {...}}, {a: {...}, b: {...}}]` You can then render this array effortlessly :) – Moritz Roessler May 16 '19 at 14:25
  • I'm sorry, I do not know what's going on. :( Is it about using any particular property or function? – kml May 16 '19 at 14:33
  • I still have a problem with this sorting. If there are more than two of the same "otherid" values ​​then it does not work as it should. – kml May 16 '19 at 15:42
0

The key to sorting strings is to use String.localeCompare(). Numbers, dates and booleans are much simpler.

Here is an example of sorting a list of Objects by two string columns - name and menu:

arr.sort(function comparerFn(L, R){
    if(L.name !== R.name) 
        return (new String(L.name)).localeCompare(R.name)===1?1:-1
    if(L.menu !== R.menu) 
        return (new String(L.menu)).localeCompare(R.menu)===1?1:-1
    return 0
})

Reasoning for odd ===1?1:-1 syntax: localeCompare() returns 1 or 0 but sort compareFn requires either 0: (leave sorting as-is), >0: (L is before R), <0: (R is before L)

Timothy C. Quinn
  • 3,739
  • 1
  • 35
  • 47