简体   繁体   English

JavaScript对象排序

[英]JavaScript objects sorting

Ive got an array of objects, something like this: 我有一个对象数组,像这样:

tab = [
{ top: true, i: 2, bottom: false },
{ top: true, i: 5, bottom: false },
{ top: true, i: 6, bottom: false },
{ top: false, i: 1, bottom: false },
{ top: false, i: 8, bottom: false },
{ top: false, i: 1, bottom: false },
{ top: false, i: 2, bottom: true },
{ top: false, i: 3, bottom: true },
{ top: false, i: 1, bottom: true },
{ top: true, i: 5, bottom: false }
]

And I want to sort it, lets say we have object A and B: 我想对它进行排序,可以说我们有对象A和B:

  1. if top == true, put it at the top of the list 如果top == true,则将其放在列表的顶部
  2. if Ai == Bi, put A and B next to each other no matter what 如果Ai == Bi,则无论如何都将A和B彼此相邻
  3. if bottom == true, put it at the end of list 如果bottom == true,则将其放在列表的末尾

So the array from above, sorted would look something like this: 因此,上面排列的数组看起来像这样:

{ top: true, i: 2, bottom: false },
{ top: false, i: 2, bottom: true },
{ top: true, i: 5, bottom: false },
{ top: true, i: 5, bottom: false },
{ top: true, i: 6, bottom: false },
{ top: false, i: 8, bottom: false },
{ top: false, i: 1, bottom: false },
{ top: false, i: 1, bottom: false },
{ top: false, i: 1, bottom: true },
{ top: false, i: 3, bottom: true }

Im using Array.sort, but I cant make it work and it drives me crazy, any idea? 我正在使用Array.sort,但是我无法使它正常工作,这让我发疯了,知道吗?

EDIT: I see that the rules arent clear enough, so Ill try to be more specify now: 编辑:我看到规则arent不够清楚,所以我现在尝试更详细地指定:

  1. if Ai == Bi, put A and B next to each other no matter what 如果Ai == Bi,则无论如何都将A和B彼此相邻
  2. if top == true, put it at the top of the list 如果top == true,则将其放在列表的顶部
  3. if bottom == true, put it at the end of list 如果bottom == true,则将其放在列表的末尾

  4. A.top: true, A.bottom: true - impossible case A.top:是,A.bottom:是-不可能的情况

  5. A.top: true, B.top: true, Ai != Bi - order doesnt matter, same with bottom A.top:true,B.top:true,Ai!= Bi-顺序无关紧要,与底部相同
  6. top has higher priority then botttom, so if A.top: true, B.bottom: true, Ai = Bi then we put them at the top top的优先级高于botttom,因此如果A.top:true,B.bottom:true,Ai = Bi,则将其放在顶部

You can use JavaScript's built in sort method for arrays. 您可以将JavaScript的内置排序方法用于数组。 It accepts a callback, which can be used to compare the items to determine the sort order. 它接受一个回调,该回调可用于比较各项以确定排序顺序。 The callback is called with pairs of items from the array. 使用数组中的成对项调用回调。 If the first argument provided to the callback is to appear first, return a negative number, if it doesn't matter return 0, and if the second is to appear first return a positive number. 如果提供给回调的第一个参数首先出现,则返回负数;如果没关系,则返回0;如果第二个参数首先出现,则返回正数。 In your case, the call would look something like this: 在您的情况下,呼叫看起来像这样:

 var tab = [ { top: true, i: 2, bottom: false }, { top: true, i: 5, bottom: false }, { top: true, i: 6, bottom: false }, { top: false, i: 1, bottom: false }, { top: false, i: 8, bottom: false }, { top: false, i: 1, bottom: false }, { top: false, i: 2, bottom: true }, { top: false, i: 3, bottom: true }, { top: false, i: 1, bottom: true }, { top: true, i: 5, bottom: false } ]; var hasTop = {}; var hasBottom = {}; tab.forEach(function (t) { if (t.top) { hasTop[ti] = true; } if (t.bottom) { hasBottom[ti] = true; } }); tab.sort(function (a, b) { if (hasTop[ai] && hasTop[bi]) { return ai - bi; } else if (hasTop[ai] && !hasTop[bi]) { return -1; } else if (!hasTop[ai] && hasTop[bi]) { return 1; } else if (hasBottom[ai] && hasBottom[bi]) { return ai - bi; } else if (hasBottom[ai] && !hasBottom[bi]) { return 1; } else if (!hasBottom[ai] && hasBottom[bi]) { return -1; } else { return 0; } }); document.getElementById("foo").innerText = JSON.stringify(tab, null, 4); 
 #foo { white-space: pre; } 
 <div id="foo"> </div> 

Also, be aware that the sort built-in sorts the array in place instead of creating a new sorted array. 另外,请注意内置的sort对数组进行了适当排序,而不是创建新的sorted数组。

EDIT: 编辑:

In the original reply, I misunderstood the description of the rules, but after the update and more careful consideration I have figured out the problem. 在原始答复中,我误解了规则的描述,但是在进行了更新和更仔细的考虑之后,我发现了问题所在。 The sort order depends not just on the local properties of the two items, but whether any item with the same index ( i property) has a top or bottom property which is true, a global property of the array. 排序顺序不仅取决于两个项目的局部属性,还取决于具有相同索引( i属性)的任何项目的topbottom属性是否为true,即数组的全局属性。 In order to handle this, you must make a pass through the data and record if there is any item with a top or bottom property which is true with the given index. 为了处理此问题,您必须对数据进行遍历并记录是否有top属性或bottom属性对给定索引为true的任何项目。 There may be a clever way to do this while inside the sort callback, but I did not see one. 在sort回调中可能有一种聪明的方法,但是我没有看到。 Also, note that my original post got the sign of the return value of the sort callback wrong. 另外,请注意,我的原始帖子得到的排序回调返回值的符号错误。 It has been corrected in this edit. 在此编辑中已对其进行了纠正。

This is a proposal with a single sort and an object for sort order. 这是带有单个排序和一个排序对象的建议。 It uses a value as default value of 1e6 , big enough to be greater than the value of i . 它使用默认值1e6作为值,该值足够大以大于i的值。 If not assigned, it uses the half value of it. 如果未分配,则使用其一半。

 var tab = [{ top: true, i: 2, bottom: false }, { top: true, i: 5, bottom: false }, { top: true, i: 6, bottom: false }, { top: false, i: 1, bottom: false }, { top: false, i: 8, bottom: false }, { top: false, i: 1, bottom: false }, { top: false, i: 2, bottom: true }, { top: false, i: 3, bottom: true }, { top: false, i: 1, bottom: true }, { top: true, i: 5, bottom: false }], object = { top: {}, bottom: {} }; tab.forEach(function (t) { object.top[ti] = object.top[ti] || 0.5e6; object.bottom[ti] = object.bottom[ti] || 0.5e6; if (t.top) { object.top[ti] = ti; } if (t.bottom) { object.bottom[ti] = 1e6 + ti; } }); tab.sort(function (a, b) { return object.top[ai] - object.top[bi] || object.bottom[ai] - object.bottom[bi]; }); console.log(tab); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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