首先选择更高效的排序方式

时间:2015-12-25 02:13:15

标签: javascript performance sorting

我上面有一张表和一张地图,其中包含与下面的表行相关的标记。当用户在上面的地图上选择项目时,它突出显示匹配的行,然后将这些行移动到表格的顶部,但按用户的排序设置进行排序。

例如,如果您有此原始数据(不显示数据):

[
  {id: 1, name: 'Z'},
  {id: 2, name: 'Y'},
  {id: 3, name: 'X'},
  {id: 4, name: 'W'}
]

然后,用户在地图上选择id: 1id: 3,并按name排序。数据变为:

[
  {id: 3, name: 'X'}, // selected
  {id: 1, name: 'Z'}, // selected
  {id: 4, name: 'W'}, // not selected
  {id: 2, name: 'Y'}  // not selected
]

有一些数据集有10,000多行,我担心由于2个过滤器+ concat而选择项目时锁定时间太长。有没有办法在一次通过中执行此操作或只是一种方法来防止浏览器在执行此操作时锁定?

  var selectedRows = rows.filter(function (row) {
    return selectedMarkerIds.indexOf(row.id) !== -1
  });

  var nonSelectedRows = rows.filter(function (row) {
    return selectedMarkerIds.indexOf(row.id) == -1
  });

  var allRows = selectedRows.concat(nonSelectedRows);

  myTable.updateRowSort(allRows);

4 个答案:

答案 0 :(得分:1)

尝试减少。在回调函数中,它检查是否选择了行,并将其推送到结果对象中的相应数组。您可以在一次传递中执行此操作,然后在最后一步中连接数组。

Set

我也是lodash的忠实粉丝,这是lodash的实施。我首先将数组传递给链函数,该函数基本上将它包装在lodash包装器周围,该包装器能够链接lodash函数。然后我通过我的reduce函数传递数组,类似于我上面用var result = rows.reduce((result, row) => { selectedMarkerIds.indexOf(row.id) !== -1 ? result.selected.push(row) : result.notSelected.push(row); return result; }, { selected: [], notSelected: [] }); result.selected.concat(result.notSelected); 所做的,但这次结果的初始值是两个数组的数组:第一个数组用于选定的行第二个是非选定行。然后我使用Array.prototype.reduce展平嵌套数组,所以现在我们有一个对象数组而不是数组数组。我调用value来解包lodash包装器并获取我的finally值,这是一个行数组。

_.flatten

答案 1 :(得分:0)

不是每次用户更新时重新排序,而是保留两个持久数组。一个用于选定项目,一个用于未选择的项目。当用户选择一个项目时,将其从未选择的项目数组中拼接出来,并将其推入所选的项目数组中。然后通过连接这两个数组来更新最终数组。

你最终可能会得到以下内容:

{{1}}

...其中selectedItems和nonSelectedItems是在任何事件处理程序范围之外的数组,在用户选择某些内容时调用它来更新顺序。

答案 2 :(得分:0)

要保留原始索引,您需要为每条记录添加.index属性:

var indexed = rs.map( function(el,index) { el.index = index; return el; } );

然后排序很简单:

var sorted = indexed.sort(function(a,b) {
  var asel = selectedMarkerIds.indexOf(a.id) !== -1;
  var bsel = selectedMarkerIds.indexOf(b.id) !== -1; 

  if( asel && bsel )
    return a.name < b.name ? -1:1;

  if( asel ) return -1;
  if( bsel ) return +1;

  // both records are in not selected set
  return a.index - b.index;
});

答案 3 :(得分:0)

在每个选择中再使用一个变量selected-index = 0 - increment。如果您想使用排序位置迭代0 to selected-index并使用splice