Waiting for the outcome of a function that calls itself repeatedly

The solve function provided here is designed to sort elements in an array based on their frequency and value. However, when dealing with longer input arrays, it encounters a 'Cannot read property' error which disrupts the sorting process.

To address this issue, the function was modified to be asynchronous in order to properly handle recursive operations and wait for results. Despite these changes, the function now displays a Promise {<pending>} immediately upon execution.

If you have any insights or suggestions on what might be causing this problem, your input would be greatly appreciated!

Thank you in advance!

function sameCountSort(arr) {
  return new Promise(resolve => {
    let done = true;
    let result = [...arr];
    for (let i = 0; i < result.length - 1; i++) {
      if (result[i][1] === result[i + 1][1] && result[i][0] > result[i + 1][0]) {
        let temp = [...result[i]];
        result.splice(i, 1);
        result.splice(i + 1, 0, temp);
        done = false;
      }
    }
    if (!done) {
      sameCountSort(result);
    } else {
    resolve(result);
    } 
  })
}

async function solve(arr){
  const numberCount = {};
  
  for (let i = 0; i < arr.length; i++) {
    if (numberCount[arr[i]]) {
      numberCount[arr[i]]++;
      } else {
        numberCount[arr[i]] = 1;
      }
  }
    
  const sortedNumberCountAsArray = Object.entries(numberCount).sort((a, b) => b[1] - a[1]);
    
  const internallySorted = await sameCountSort(sortedNumberCountAsArray);
    
  let result = [];

  internallySorted.forEach((entry) => {
    result = [...result, ...new Array(entry[1]).fill(parseInt(entry[0], 10))];    
  })
  return result;  
}

solve([ 0, 1, 3, 6, 8, 8, 10, 12, 14, 17, 21, 21, 22, 26, 34, 34, 36, 38, 40, 40, 44, 45 ]);

In its original form, the code displayed above worked correctly for the first call of solve but failed for subsequent calls.

function sameCountSort(arr) {
    let done = true;
    let result = [...arr];
    for (let i = 0; i < result.length - 1; i++) {
        if (result[i][1] === result[i + 1][1] && result[i][0] > result[i + 1][0]) {
            let temp = [...result[i]];
            result.splice(i, 1);
            result.splice(i + 1, 0, temp);
            done = false;
        }
    }
    if (!done) {
        sameCountSort(result);
    } else {
        return result;
    }
}

function solve(arr){
  const numberCount = {};
  
  for (let i = 0; i < arr.length; i++) {
    if (numberCount[arr[i]]) {
      numberCount[arr[i]]++;
      } else {
        numberCount[arr[i]] = 1;
      }
  }
    
  const sortedNumberCountAsArray = Object.entries(numberCount).sort((a, b) => b[1] - a[1]);
    
  const internallySorted = sameCountSort(sortedNumberCountAsArray);
    
  let result = [];

  internallySorted.forEach((entry) => {
    result = [...result, ...new Array(entry[1]).fill(parseInt(entry[0], 10))];    
  })
  return result;  
}

solve([2,3,5,3,7,9,5,3,7]);
solve([ 0, 1, 3, 6, 8, 8, 10, 12, 14, 17, 21, 21, 22, 26, 34, 34, 36, 38, 40, 40, 44, 45 ]);

Answer №1

A more concise version of that code can be achieved. Here is a possible simplification:

const solve = (ns) =>
  Object .entries (ns .reduce ((a, n) => ({...a, [n]: (a[n] || 0) + 1}), {})) 
    .sort (([v1, c1], [v2, c2]) => (c2 - c1) || (v1 - v2))
    .flatMap (([v, c]) => Array (c) .fill (Number (v)))

console .log (
  solve ([2, 3, 5, 3, 7, 9, 5, 3, 7]) .join (' ')
)
console .log (
  solve (
    [0, 1, 3, 6, 8, 8, 10, 12, 14, 17, 21, 21, 22, 26, 34, 34, 36, 38, 40, 40, 44, 45]
  ) .join (' ')
)

Using this input

solve ([4, 2, 3, 3, 4, 1, 3, 4, 5])

The process begins with the reduce function to create an object counting the occurrences like this:

{"1": 1, "2": 1, "3": 3, "4": 3, "5": 1}

Then converting it using Object.entries results in:

[["1", 1], ["2", 1], ["3", 3], ["4", 3], ["5", 1]]

Sorting is done efficiently in one pass by subtracting counts first and then values if needed. The sorted array looks like this:

[["3", 3], ["4", 3], ["1", 1], ["2", 1], ["5", 1]]

Each value-count pair is then mapped into an array with length equal to count, and due to using flatMap, these arrays are flattened to produce:

[3, 3, 3, 4, 4, 4, 1, 2, 5]

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

"Combining AngularJS with Material Design disrupts the functionality of infinite scroll

Issue: Infinite scroll is loading all pages at once instead of waiting for the user to scroll to the page bottom. Environment: AngularJS 1.3.17 Materials Design 0.10.0 Infinite scroll script: https://github.com/sroze/ngInfiniteScroll Demo being used: The ...

Navigating through the concept of passing objects by reference in child components of Angular 2+

Understanding that TypeScript uses object passing by reference can be challenging, especially when dealing with deep copy issues. This becomes particularly cumbersome when working within a theme. I recently encountered an issue with a component containing ...

Utilizing inline JavaScript to automatically refresh a webpage at specified intervals and monitor for updates within a specific div element

I am currently working on creating an inline script that will automatically refresh a webpage at regular intervals and check for changes in a specific element. If the element meets certain criteria, then the script should proceed to click on a designated b ...

Retrieve an array of information from a firestore database query

I am encountering an issue while trying to retrieve information about all users who are friends of a specific user. I have attempted to gather the data by pushing it to an array and then returning it as a single JSON array. However, it seems that the dat ...

What advantages does utilizing an angular directive provide in the context of a comment?

Up to now, I have primarily used Directives in the form of Elements or Attributes. Is the Comment style directive simply a matter of personal preference for style? app.directive('heading', [function () { return { replace: true, ...

How to send a JSON Object and a CSV file using FormData

I need to send a JSON Object and a CSV file in a fetch request from my frontend to my backend. The JSON object is stored in the headerIngestion variable, while the CSV file is saved in the csv state. let formData = new FormData(); formData.append('h ...

The horizontal overflow in the HTML code was unsuccessful

I stumbled upon an interesting issue where I applied a div with specific styling: overflow-x: scroll However, the outcome was not as expected. Instead of overflowing, the content simply started on a new line. Here is the source code for reference: & ...

Preventing v-stepper-step header click in Vuetify.js when form is invalid

I'm using Vuetify's v-stepper component. What I'm trying to achieve is: When a user clicks on a stepper step in the header, I want to block the click event if the active form is not valid. I have been able to accomplish this by attaching ...

NextJS function utilizes its own references within React and automatically fetches data without the need for an import

I recently purchased this template and I'm trying to figure out which page the code snippet "{getLayout(<Component {...pageProps} />)}" is directed to during the initial load. It seems like it might be a global variable hidden somewher ...

magnific popup: trigger the display by clicking on an element other than the image

A recent request from the client calls for the image caption to cover the thumbnail fully when hovered over. To meet this requirement, I now need to enable clicking on the caption to open Magnific Popup rather than using the <a> tag. Here is what I h ...

The CSS Bootstrap 4 class 'input-group-append' is not functioning properly. Just recently, the styles were displaying correctly

My web application using AngularJS 1.7.8, jQuery 3.3.1, Bootstrap 4.3.1, and various other CSS and JS libraries worked seamlessly last week. However, today I noticed an issue with the button visualization. To Replicate: Visit openskymap.org to see my d ...

Dealing with null route parameters for Express applications

I am facing a challenge in handling an empty route parameter when a path is not specified. My intention is to return a new date if the route parameter is empty. However, the server's response so far is: Cannot GET /api/timestamp/ app.get("/api/timest ...

Tips for showcasing elements individually in JavaScript when a button is clicked and halting on a random element

I have some names stored in h3 tags. I want to highlight one name at a time when I click a button, stopping at a random name. <div class="all-names"> <h3 class="name-one"><span class="line">Name ...

struggle with converting JSON string into an array from server

After receiving JSON data from the server, I attempted to convert it into an array using: JSON.parse(response.data.blocks) However, I encountered this error: SyntaxError: Unexpected token o in JSON at position 1 at JSON.parse (<an ...

A step-by-step guide on extracting the image source from a targeted element

Here is a snippet of my HTML code containing multiple items: <ul class="catalog"> <li class="catalog_item catalog_item--default-view"> <div class="catalog_item_image"> <img src="/img/01.png" alt="model01" class="catalog_it ...

Create a timer that plays music when a button is pressed

My goal is to initiate a timer when a specific button is clicked. While there are many timers available that start upon page load, I have not been able to find one that begins upon clicking a button. Additionally, the timer must start at the same time as ...

Creating an object instance in Angular 2 using TypeScript

Looking for guidance on creating a new instance in TypeScript. I seem to have everything set up correctly, but encountering an issue. export class User implements IUser { public id: number; public username: string; public firstname: string; ...

Ways to confirm if there have been any updates in Kendo Observable

Hey there! I have a form with specific fields that I've converted to Kendo Observable like this: var TITLE = $("#TITLE").val().trim(); var DESC = $("#DESC").val().trim(); Analysis.Kendo_VM = kendo.observable({ TITLE: TITLE != null ? TITLE : ...

Nextjs Version 13: Implementing a Loading UI for Search Parameter Changes

I am working on a component that handles user input and updates search parameters accordingly. This results in a page refresh to display updated data on the UI. However, despite these actions, the loading.tsx file for this route is not being triggered. Af ...

End of container Bootstrap 4 row with two columns at the edge

I'm currently working on an angular project with bootstrap 4. Within the container, there are two rows. I specifically want one row to always be positioned at the bottom of the container. Despite trying methods like justify-content: flex-end;, botto ...