简体   繁体   中英

JavaScript/React Native array(objects) sort

I'm starting with react-native building an app to track lap times from my RC Cars. I have an arduino with TCP connection (server) and for each lap, this arduino sends the current time/lap for all connected clients like this:

{"tx_id":33,"last_time":123456,"lap":612}

In my program (in react-native), I have one state called dados with this struct:

dados[tx_id] = {
  tx_id: <tx_id>, 
  last_time:,
  best_lap:0,
  best_time:0,
  diff:0,
  laps:[]
};

This program connects to arduino and when receive some data, just push to this state. More specific in laps array of each transponder. Finally, I get something like this:

dados[33] = {
  tx_id:33,
  last_time: 456,
  best_lap: 3455,
  best_time: 32432,
  diff: 32,
  laps: [{lap:1,time:1234},{lap:2,time:32323},{lap:3,time:3242332}]
}
dados[34] = {
  tx_id:34,
  last_time: 123,
  best_lap: 32234,
  best_time: 335343,
  diff: 10,
  laps: [{lap:1,time:1234},{lap:2,time:32323},{lap:3,time:3242332}]
}
dados[35] = {
  tx_id:35,
  last_time: 789,
  best_lap: 32234,
  best_time: 335343,
  diff: 8,
  laps: [{lap:1,time:1234},{lap:2,time:32323},{lap:3,time:3242332},{lap:4,time:343232}]
}

This data in rendered to View 's using map function (not a FlatList). My problem now is that I need to order this before printing on screen.

Now, with this code, data are printed using tx_id as order, since it's the key for main array. Is there a way to order this array using number of elements in laps property and the second option to sort, use last_time property of element?

In this case, the last tx of my example ( 35 ) would be the first in the list because it has one lap more than other elements. The second item would be 34 (because of last_time ). And the third would be tx 33 .

Is there any way to to this in JavaScript, or I need to create a custom functions and check every item in recursive way?!

Tks @crackhead420

While waiting for reply to this question, I just found what you said.... :)

This is my final teste/solution that worked:

var t_teste = this.state.teste;
    t_teste[33] = {tx_id: 33, last_time:998,best_lap:2,best_time:123,diff:0,laps:[{lap:1,time:123},{lap:2,time:456}]};
    t_teste[34] = {tx_id: 34, last_time:123,best_lap:2,best_time:123,diff:0,laps:[{lap:1,time:123},{lap:2,time:456}]};
    t_teste[35] = {tx_id: 35, last_time:456,best_lap:2,best_time:123,diff:0,laps:[{lap:1,time:123},{lap:2,time:456},{lap:3,time:423}]};
    t_teste[36] = {tx_id: 36, last_time:789,best_lap:2,best_time:123,diff:0,laps:[{lap:1,time:123},{lap:2,time:456}]};

    console.log('Teste original: ',JSON.stringify(t_teste));

    var saida = t_teste.sort(function(a, b) {
      if (a.laps.length > b.laps.length) {
        return -1;
      }
      if (a.laps.length < b.laps.length) {
        return 1;
      }
      // In this case, the laps are equal....so let's check last_time
      if (a.last_time < b.last_time) {
        return -1; // fastest lap (less time) first!
      }
      if (a.last_time > b.last_time) {
        return 1;
      }
      // Return the same
      return 0;

    });

    console.log('Teste novo: ',JSON.stringify(saida));

Using some simple helper functions, this is definitely possible:

 const data = [{tx_id:33,last_time:456,best_lap:3455,best_time:32432,diff:32,laps:[{lap:1,time:1234},{lap:2,time:32323},{lap:3,time:3242332}]},{tx_id:34,last_time:123,best_lap:32234,best_time:335343,diff:10,laps:[{lap:1,time:1234},{lap:2,time:32323},{lap:3,time:3242332}]},{tx_id:35,last_time:789,best_lap:32234,best_time:335343,diff:8,laps:[{lap:1,time:1234},{lap:2,time:32323},{lap:3,time:3242332},{lap:4,time:343232}]}] const sortBy = fn => (a, b) => -(fn(a) < fn(b)) || +(fn(a) > fn(b)) const sortByLapsLength = sortBy(o => o.laps.length) const sortByLastTime = sortBy(o => o.last_time) const sortFn = (a, b) => -sortByLapsLength(a, b) || sortByLastTime(a, b) data.sort(sortFn) // show new order of `tx_id`s console.log(data.map(o => o.tx_id)) 

sortBy() (more explanation at the link) accepts a function that selects a value as the sorting criteria of a given object. This value must be a string or a number. sortBy() then returns a function that, given two objects, will sort them in ascending order when passed to Array.prototype.sort() . sortFn() uses two of these functions with a logical OR || operator to employ short-circuiting behavior and sort first by laps.length (in descending order, thus the negation - ), and then by last_time if two objects' laps.length are equal.

Its possible to sort an object array by theire values:

dados.sort(function(a, b) {
   return a.last_time - b.last_time;
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM