JavaScript/React Native 数组(对象)排序

3

我开始使用React Native构建一款应用,用于记录我的遥控汽车的圈速。我有一个带有TCP连接(服务器)的Arduino板,每个圈速时,该Arduino会将当前时间/圈速发送给所有已连接的客户端,如下所示:

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

在我的程序中(使用react-native开发),我有一个叫做dados的状态,其结构如下:
dados[tx_id] = {
  tx_id: <tx_id>, 
  last_time:,
  best_lap:0,
  best_time:0,
  diff:0,
  laps:[]
};

这个程序连接到Arduino,当接收到一些数据时,就将其 push 到这个状态。更具体地说,在每个transponder的 laps 数组中。最终,我得到了类似于这样的结果:

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}]
}

这些数据使用map函数呈现在View中(而不是FlatList)。现在我的问题是,在打印到屏幕之前,我需要对这些数据进行排序。
现在,使用此代码,数据使用tx_id作为顺序进行打印,因为它是主数组的键。有没有一种方法可以按照laps属性中的元素数量对数组进行排序,并且第二个选项是使用元素的last_time属性进行排序?
在这种情况下,我的示例中最后一个tx35)将成为列表中的第一个,因为它比其他元素多一个圈。第二个项目将是34(因为last_time)。第三个将是tx33
在JavaScript中是否有任何方法来实现这一点,还是我需要创建自定义函数并以递归方式检查每个项?!
3个回答

1

通过使用一些简单的辅助函数,这是完全可能的:

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()(更多解释请参见链接)接受一个函数作为给定对象的排序标准选择值。这个值必须是一个字符串或一个数字。sortBy()然后返回一个函数,给定两个对象时,将在传递给Array.prototype.sort()时按升序对它们进行排序。sortFn()使用两个这样的函数和逻辑OR ||运算符来使用短路行为,首先按laps.length(按降序排列,因此有否定号-),然后按last_time排序,如果两个对象的laps.length相等。


1

谢谢@crackhead420

在等待问题回复期间,我找到了你所说的... :)

这是我最终的测试/解决方案:

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

0

可以通过其值对对象数组进行排序:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接