Skip to main content

Sorting Visualizer - Why won't my highlights update when one of my swapped out bars is the next in line to get swapped in?

I'm creating a sorting visualizer, and it's implemented by using synchronous sorting algorithms that push animations to a queue to be handled in the async function animateArrayUpdate. The purpose of the highlights is to indicate the bar which is next up to get sorted. In the case of selection sort, this would be the bar at minIndex which will be swapped with the bar at the current index or i on the next iteration of the loop. The sorting/swapping works perfectly, and the highlighting mostly works, except when the following scenario occurs: The bar at i gets swapped out for a bar at minIndex and then is next up to get swapped in for the next i. In these cases, the bar that got swapped in the last iteration retains its highlight for that iteration so the newly swapped-in bar never gets highlighted. I'll show a trivial example with a mostly sorted array, but the extent to which the rest of the array is sorted is irrelevant, and this wonky highlighting behavior will happen any time the above conditions are met.

Here, the second bar is highlighted to show that it's the minimum index of this iteration and will get swapped in next.

Second bar is highlighted to show that it is next up to get sorted

Here is what happens after the swap. As you can see, the first bar retains its highlight. What needs to happen is that the first bar should lose its highlight and the second bar should become highlighted (but not swapped with anything since it's already in place) because it's the new minIndex. This is in fact what happens in all cases where a freshly swapped bar is not immediately up to get swapped again on the very next iteration, i.e., in the vast majority of cases.

First bar retains highlight, even though second bar should get highlighted here

  const selectionSort = (arr) => {
    const animations = [];
    const copy = [...arr];
    for (let i = 0; i < copy.length - 1; i++) {
      let minIdx = i;
      for (let j = i + 1; j < copy.length; j++) {
        if (copy[j].correctPos < copy[minIdx].correctPos) {
          minIdx = j;
        }
      }
      animations.push({
        action: "color",
        arr: [...copy],
        highlightedIndex: minIdx,
        swap1: i,
        swap2: minIdx,
      });
      swapBarsMutable(copy, i, minIdx);
      animations.push({
        action: "move",
        arr: [...copy],
        highlightedIndex: minIdx,
        swap1: i,
        swap2: minIdx,
      });
    }
    return animations;
  };

  const animateArrayUpdate = async (animations) => {
    for (let i = 0; i < animations.length; i++) {
      const anim = animations[i];
      const bars = barsContainer.current.children;
      let highlightedBar = bars[anim.highlightedIndex];

      if (anim.action === "color") {
        highlightedBar.classList.add(barStyles["bar-highlighted"]);
        await new Promise((resolve) => {
          timers.current.push(setTimeout(resolve, 2000));
        });
      }
      highlightedBar.classList.remove(barStyles["bar-highlighted"]);

      if (anim.action === "move") {
        setBarsToRender(swapLefts(anim.arr, anim.swap1, anim.swap2));
      }
    }
    setIsPlaying(false);
  };

Here is the code. I can provide a sandbox example if the problem isn't apparent from just this fragment. Basically, the bars get rendered by a dumb component that iterates over the barsToRender stateful array. Then, the following line gets passed into the play button component and gets called onClick. Again, the general structure of the program seems to have no issues, and the highlighting problem seems pretty local. Thanks for the help!

algorithmToPlay = () => { animateArrayUpdate(selectionSort(barsToRender)); };

Edit: I was debugging and played the first two animations only, and it does appear that the highlight is removed after the swap. However, it is reapplied to the wrong bar. Furthermore, on the third animation (which is the problematic one), the highlightedIndex is correctly assigned with the value of 1. But this seems to be pointing to the bar which is now at 0 for some reason.

Via Active questions tagged javascript - Stack Overflow https://ift.tt/JfaeVyQ

Comments

Popular posts from this blog

How to show number of registered users in Laravel based on usertype?

i'm trying to display data from the database in the admin dashboard i used this: <?php use Illuminate\Support\Facades\DB; $users = DB::table('users')->count(); echo $users; ?> and i have successfully get the correct data from the database but what if i want to display a specific data for example in this user table there is "usertype" that specify if the user is normal user or admin i want to user the same code above but to display a specific usertype i tried this: <?php use Illuminate\Support\Facades\DB; $users = DB::table('users')->count()->WHERE usertype =admin; echo $users; ?> but it didn't work, what am i doing wrong? source https://stackoverflow.com/questions/68199726/how-to-show-number-of-registered-users-in-laravel-based-on-usertype

Why is my reports service not connecting?

I am trying to pull some data from a Postgres database using Node.js and node-postures but I can't figure out why my service isn't connecting. my routes/index.js file: const express = require('express'); const router = express.Router(); const ordersCountController = require('../controllers/ordersCountController'); const ordersController = require('../controllers/ordersController'); const weeklyReportsController = require('../controllers/weeklyReportsController'); router.get('/orders_count', ordersCountController); router.get('/orders', ordersController); router.get('/weekly_reports', weeklyReportsController); module.exports = router; My controllers/weeklyReportsController.js file: const weeklyReportsService = require('../services/weeklyReportsService'); const weeklyReportsController = async (req, res) => { try { const data = await weeklyReportsService; res.json({data}) console

How to split a rinex file if I need 24 hours data

Trying to divide rinex file using the command gfzrnx but getting this error. While doing that getting this error msg 'gfzrnx' is not recognized as an internal or external command Trying to split rinex file using the command gfzrnx. also install'gfzrnx'. my doubt is I need to run this program in 'gfzrnx' or in 'cmdprompt'. I am expecting a rinex file with 24 hrs or 1 day data.I Have 48 hrs data in RINEX format. Please help me to solve this issue. source https://stackoverflow.com/questions/75385367/how-to-split-a-rinex-file-if-i-need-24-hours-data