单项数组上的 Array.sort() 是否在不触发回调函数的情况下返回?

and*_*ins 1 javascript sorting recursion

我正在利用 Array.sort() 对对象数组进行递归排序,每个对象都可能有子对象。

window.sortByrecent = function (a, b) {
  if(a.children && !a.isSorted) {
    a.children = a.children.sort(window.sortByrecent);
    a.isSorted = true;
  }

  if(b.children && !b.isSorted) {
    b.children = b.children.sort(window.sortByrecent);
    b.isSorted = true;
  }

  // Later post comes first
  return moment(b.date).unix() - moment(a.date).unix();
}
Run Code Online (Sandbox Code Playgroud)

这是由

this.comments.sort(window.sortByrecent);
Run Code Online (Sandbox Code Playgroud)

然而,某些帖子没有排序,我正在努力找出原因。在调试器中逐步执行它,看起来如果 a.children 是一个数组,它实际上从未触发递归回调,这意味着它从不检查该评论的子项,因此从不对其进行排序。

有没有办法强制递归?

- - - - 答案 - - - -

this.comments = window.sortByrecent(this.comments);

window.sortByrecent = function (arr) {
  if(!arr.isSorted) {
    arr.sort(window.compareByRecentNewFirst);

    arr.forEach(function(element, index, array) {
      if(array[index].children) {
       array[index].children = window.sortByrecent(array[index].children);
      }
    });

    arr.isSorted = true;
  }

  return arr;
}

window.compareByRecentNewFirst = function(a, b) {
  return moment(b.date).unix() - moment(a.date).unix();
}
    
Run Code Online (Sandbox Code Playgroud)

Cer*_*nce 5

您通常不应在.sort回调中排序(或执行副作用),因为:

  • 元素相互比较的顺序可能取决于实现
  • 如果副作用(例如排序子属性)很昂贵,那么您可能会不必要地执行比需要更多的次数。排序是一个O(n log n)过程;你不需要对每个子数组进行排序log n,你只需要每 1 次排序。

你可能想要这样的东西:

const recursiveSort = arr => {
  if (!arr.isSorted) {
    arr.sort((a, b) => moment(b.date).unix() - moment(a.date).unix());
    for (const { children } of arr) {
      if (children) recursiveSort(children);
    }
    arr.isSorted = true;
  }
};
Run Code Online (Sandbox Code Playgroud)