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:
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?
EDIT: I see that the rules arent clear enough, so Ill try to be more specify now:
if bottom == true, put it at the end of list
A.top: true, A.bottom: true - impossible case
You can use JavaScript's built in sort method for arrays. 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. 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.
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. 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. There may be a clever way to do this while inside the sort callback, but I did not see one. 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
. 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);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.