3

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?!

Rick
  • 4,030
  • 9
  • 24
  • 35

3 Answers3

1

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));
1

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.

Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
0

Its possible to sort an object array by theire values:

dados.sort(function(a, b) {
   return a.last_time - b.last_time;
});
nichtgian
  • 113
  • 1
  • 4
  • 13