Organizing numbers in Chrome using Array.sort()

While attempting to reorganize an array of divs based on their positions relative to each other, I encountered a peculiar issue. After spending considerable time troubleshooting in CodePen, it became apparent that Chrome's sorting behavior gets erratic for arrays with ten or more elements.

var array = [0,1,2,3,4,5,6,7,8,9,10];
array.sort(function(a, b) {
        return -1;
});

The output from Chrome was unexpected:

[0, 2, 3, 4, 1, 6, 7, 8, 9, 10, 5]

Further investigation revealed the underlying algorithm used by Chrome, which explains this anomaly. While familiar with using a-b to sort, I needed a different approach due to the specific positioning criteria involved. The array consists of jQuery objects representing divs, and my goal is to arrange them visually based on vertical and horizontal proximity.

In response to initial attempts, I revised the comparison function to output either 1, -1, or 0. Despite these adjustments, the results were not as intended.

Subsequently, a workaround was devised utilizing a forEach loop to evaluate the items against each other and adjust the z-index accordingly:

function setTileZIndex() {
        var $tiles = $('.grid__item__wrap');
        var coords = [];
        $tiles.each(function(index) {
            var topLeft = $(this).offset();
            var obj = {
                bottom: topLeft.top + $(this).height(),
                left: topLeft.left,
                top: topLeft.top,
                right: topLeft.left + $(this).width(),
                $this: $(this),
                z: 9999
            };
            coords.push(obj);
        });

        coords.forEach(function(a) {
            coords.forEach(function(b) {
                if (a.bottom < b.top)
                    b.z += 4;
                if (a.left > b.right)
                    b.z += 1;
            })
        });

        coords.forEach(function(elt) {
            elt.$this.css('z-index', elt.z);
        });
    }

Answer №1

REVISED

Your initial question seems to have oversimplified the scenario. Here is an updated response:

I am seeking a method where a precedes b if a is positioned below or to the left of b. Any guidance?

In this instance, ensure that you compare the corresponding edges of each object – for example, compare a.left with b.left, and a.bottom with b.bottom ...

const data = [
  { bottom:1181, left:23, right:72, top:910, },
  { bottom:906, left:23, right:183, top:801 },
  { bottom:1181, left:78, right:183, top:1132 },
  { bottom:1182, left:189, right:349, top:1021 },
  { bottom:1133, left:355, right:632, top:1132 },
  { bottom:795, left:78, right:183, top:690 },
  { bottom:1181, left:355, right:626, top:1132 },
  { bottom:1127, left:78, right:183, top:1022 },
  { bottom:1127, left:355, right:460, top:1022 },
  { bottom:1127, left:466, right:571, top:1022, },
  { bottom:1016, left:78, right:183, top:911 },
]

data.sort((a,b) => {
  if (a.left < b.left || a.bottom < b.bottom)
    return -1
  else if (a.right > b.right || a.top > b.top)
    return 1
  else
    return 0
})

console.log(data)
// [ { bottom: 906, left: 23, right: 183, top: 801 },
//   { bottom: 1181, left: 23, right: 72, top: 910 },
//   { bottom: 795, left: 78, right: 183, top: 690 },
//   { bottom: 1016, left: 78, right: 183, top: 911 },
//   { bottom: 1127, left: 78, right: 183, top: 1022 },
//   { bottom: 1182, left: 189, right: 349, top: 1021 },
//   { bottom: 1133, left: 355, right: 632, top: 1132 },
//   { bottom: 1181, left: 78, right: 183, top: 1132 },
//   { bottom: 1127, left: 355, right: 460, top: 1022 },
//   { bottom: 1181, left: 355, right: 626, top: 1132 },
//   { bottom: 1127, left: 466, right: 571, top: 1022 } ]


Prior Solution

While this topic may have been addressed elsewhere on this platform, it is crucial that your comparator must yield values of -1, 0, and 1 for the desired outcome.

  • -1 positions a to the left of b
  • 1 places a to the right of b
  • 0 results in no change in the position of either a or b

let sorted = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].sort((a,b) => {
  if (a < b)
    return -1
  else if (a > b)
    return 1
  else
    return 0
})

console.log(sorted)
// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]


Alternatively, you can employ concise yet intricate chained ternary expressions for sorting.

let sorted = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].sort((a,b) =>
  a < b ? -1 : a > b ? 1 : 0
)

console.log(sorted)
// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]


Remember, elements within the array are not always compared in the expected order – hence, do not assume compare(0,1) followed by compare(1,2), then compare(2,3), etc.

let sorted = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].sort((a,b) => {
  console.log(a,b)
  return a < b ? -1 : (a > b ? 1 : 0)
})
// 0 10
// 0 5
// 10 5
// 2 5
// 3 5
// 4 5
// 1 5
// 6 5
// 9 5
// 8 5
// 7 5
// 0 2
// 2 3
// 3 4
// 4 1
// 3 1
// 2 1
// 0 1
// 6 7
// 7 8
// 8 9
// 9 10

console.log(sorted)
//=> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

Answer №2

When creating a compare function, remember that it should have specific criteria:

  • Negative: indicates the first element should come before the second
  • Zero: means the order between elements is not important
  • Positive: shows the second element should come before the first.

Always returning -1 can lead to unpredictable outcomes.

Unfortunately, achieving what you're attempting may not be feasible because the compare function must provide consistent results for all array elements. Using your current compare function could result in f(a, b) = -1 and f(b, a) = -1, which creates inconsistency as either a or b should be prioritized.

Answer №3

I apologize for any confusion in my previous explanation. The key requirement for the resulting array is that if a box is entirely above OR to the right of another box,

(a.bottom < b.top || a.left > b.right)

it should be positioned after the other box.

One specific condition set can be expressed as

a.bottom < b.top || a.left > b.right ? 1 : -1

which can be confirmed through the use of .reduceRight() method.

var coords = [
  
  {
    bottom:1181.8854675292969,
    left:23.39583396911621,
    right:72.39583396911621,
    top:910.8854675292969,
  },
  
  {
    bottom:1181.3750305175781,
    left:78.39583587646484,
    right:183.39583587646484,
    top:1132.3750305175781
  },
  
  ...
  
];

coords.sort((a, b) => a.bottom < b.top || a.left > b.right ? 1 : -1);

console.log(coords);

coords.reduceRight((a, b) => {console.log(a.bottom < b.top || a.left > b.right); return b});

Answer №4

Check out this handy function for comparing values.

var array = [25, 6, 13, 29, 13];

function customCompareFunction(x, y) {
    return x > y ? 1 : x === y ? 0 : -1;
}

var orderedArray = array.sort(customCompareFunction);

console.log(orderedArray);

Answer №5

Ensure to test the code on both Chrome and Edge browsers for compatibility. In Chrome, the sorting may not be stable if the return value is consistent across all comparisons.

var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
array.sort(function(a, b) { return 0; });
console.log(array); // Output in Chrome: [5, 0, 2, 3, 4, 1, 6, 7, 8, 9, 10]
                    // Output in Edge:   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
array.sort(function(a, b) { return 1; });
console.log(array); // Output in Chrome: [5, 10, 0, 9, 8, 7, 6, 1, 4, 3, 2]
                    // Output in Edge:   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
array.sort(function(a, b) { return -1; });
console.log(array); // Output in Chrome: [0, 2, 3, 4, 1, 6, 7, 8, 9, 10, 5]
                    // Output in Edge:   [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Subtracting arrays with conditions

I am currently working with two arrays that store information about my products. Here is a sample of the data: $transfer_in array Array ( [0] => Array ( [product_id] => 2 [product_qty] => 32 ...

Exploring TypeScript and React Hooks for managing state and handling events

What are the different types of React.js's state and events? In the code snippet provided, I am currently using type: any as a workaround, but it feels like a hack. How can I properly define the types for them? When defining my custom hooks: If I u ...

How do I resolve the issue of the `translate` array in `setup()` in `vuei18n` requiring an additional step or load to render the translations in the `<template/>`?

Apologies for the mention of the "extra step/load" aspect; I acknowledge that it may come across as vague and not the best choice of words. Allow me to illustrate with code snippets and two accompanying images. 1st: https://i.sstatic.net/QtDXD.png Here is ...

The result of JWT.decode may be null

I am facing an issue with decoding a JSON web token as it is returning null. I have even tried setting complete set to true, but unfortunately it still fails. The function used for generating the token is: import jwt from 'jsonwebtoken'; jwt.s ...

Can you explain the functionality of the cin.get() function?

Can you explain to me how the cin.get() function operates? Suppose I have a char array of 256 characters. If the input consists of less than 256 characters, what will the 'empty' array elements contain? Are they all set to '\0' or ...

The button mysteriously vanishes on Github Pages, yet remains visible when viewing the

I recently completed a project on Github and created a corresponding Github Page for it. The page features multiple buttons with different functions, but oddly enough, one specific button is not showing up on the Github Page. Surprisingly, it appears perfe ...

Choosing various data using Ajax

I am currently in the process of extracting various pieces of data from my insert.php page, including the post id, username, and user id. I intend to include other selected data as well. However, when trying to echo out multiple queries, all the informatio ...

Introducing the new "Expand/Collapse" feature - enhancing the way content placement functions!

I have added a 'view all' button to toggle the visibility of a section on my website. Currently, clicking on the button reveals a long list above it, which is causing confusion for users as the button remains in the same position when clicked. T ...

Using a static string in Javascript yields no issues, whereas working with variables can sometimes cause problems

I've been struggling with a problem this morning and it's time to ask for help! I have a JavaScript function that takes the value entered by a user into an autocomplete box, uses AJAX to send that value to a PHP script which then queries the data ...

Setting cookies with NextJS Route API post middleware

@ Using NextJS 13.3 with App Dir and API Routes. I am currently working on implementing an authentication system using NextJS with my external NodeJS backend. The process involves the frontend sending credentials to the backend, which validates them and r ...

Is there a way to simulate the Bun global object using Jest?

Currently, my tech stack includes Bun, Typescript (TS), and Jest. As I work on writing my tests, I encounter the need to mock Bun.file functionality. Here is a snippet from my tsconfig.json: { "compilerOptions": { "lib": ["ESNext"], " ...

What makes YouTube videos load quicker on Chrome compared to Firefox?

After working as a Java UI & Backend developer for the past decade, I have come across some surprising browser behaviors: Firefox: When clicking on a related video on the YouTube website, there is a delay in figuring out the video followed by buffering ...

Attempting to refresh the Document Object Model (DOM) by incorporating sorted numbers and representing them visually with height bars using

Currently, I am working on creating a visualization of height bars with 40 randomly generated values similar to a sorting visualizer. I have implemented mergesort for sorting the values. Initially, when updating the DOM for the first time, I generated rand ...

What's the reason behind this file not opening?

When I try to insert this code into files index.html, style.css, and app.js, the page refuses to open. The browser constantly displays a message saying "The webpage was reloaded because a problem occurred." I am using a MacBook Air with macOS Big Sur and a ...

What is the procedure to retrieve a user object in passport.authenticate (local) once the user has successfully logged in?

Is there a way to configure the authController file so that it returns a user object when I am logged in? Currently, I am attempting to achieve this by setting res.json(req.body) in the userController file within the exports.register function. However, it ...

Implement dynamic routing in React based on a specific condition

Working on implementing a routing logic for my react application. Here's the scenario: I have 2 pages and 2 roles (user and reviewer) in my app and here's what I want to achieve: If a user accesses the app, they should be redirected to "/ ...

Is there a way to access the precise location information of a mobile phone remotely?

Currently, I am working on an Android project that requires obtaining the location details of a remote mobile phone. Here's the scenario: The manager is stationed in the office while the salesperson is out and about in a city selling products. How ca ...

Unable to append a property to each object within an array during a loop

Hey everyone, I could really use some help with this problem I'm facing. Let me explain what's going on - I'm working on pulling documents from MongoDB using Mongoose. Take a look at the array of objects that is returned from the mongoose qu ...

Implementing a dynamic dropdown list with pre-selected values within a while loop

Is there a way to have the selected value in a dropdown list reflect a value given by a JavaScript function that updates a GET parameter in the URL when an option is chosen? <?php while ($row = mysql_fetch_array($res)) { echo '<option value=&ap ...

Stopping an ajax timer when the results contain a specific key

I am currently working on a straightforward ajax function: <script type="text/javascript" src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script type="text/javascript"> function performAjaxRequest() { $.ajax({ ...