Algorithm using JavaScript to identify objects within an array

I am working with an array of objects that contain information about different projects. Each project has a unique ID and two arrays, one containing the IDs of projects that will happen before it, and another with the IDs of projects that will follow. Here's an example:

let projects = [];

projects[0] = {
    id: "ID_123",
    before: [],
    after: ["ID_523"],
}

projects[1] = {
    id: "ID_523",
    before: ["ID_123"],
    after: ["ID_523","ID_827"],
}

My goal is to identify all projects that depend on each other and group them together in subgroups. I approach this by iterating through the array starting from projects with no predecessors and then sequentially adding projects that follow into the same subgroup until there are no more subsequent projects. Here is my algorithm:

let subgroup = 0;
// loop through project array
for (let i=0; i<projects.length; i++) {
    let next = projects[i]; // next contains the next project in the row
    // find projects that have no projects happening before
    if ((!next.hasOwnProperty('subgroup')) && (next.before.length == 0)) {
        // do this as long as the next project has projects happening after
        while (next.after.length > 0) {
            // find the array-key of the first project happening afterwards
            let key;
            for (let n=0; n<projects.length; n++) {
                if (projects[n].id == next.after[0]) {
                    key = n;
                    break;
                }
            }
            // set the subgroup of the project with the key from above
            projects[key].subgroup = subgroup;
            // set the next project
            next = projects[key];
        }
        subgroup++;
    }
}

Unfortunately, my algorithm does not assign subgroups to some projects as intended. Despite spending days trying to debug it, I cannot seem to locate the error.

If anyone can help me identify what I'm doing wrong, I would greatly appreciate it. Thank you in advance!

Answer №1

Your code is currently only focusing on after[0] and not considering other IDs present in the after property. It's important to also take into account dependencies indicated by the before property, as you might have multiple predecessors leading to a project, all of which should fall under the same subgroup.

To optimize your search process, create a Map that will store each project with its corresponding ID as the key.

In order to cover all entries listed in the after and before properties, it's recommended to implement a breadth-first search approach: add all dependent projects to a queue while disregarding those already visited (using a Set):

let projects = [{
    id: "ID_123",
    before: [],
    after: ["ID_523"],
}, {
    id: "ID_523",
    before: ["ID_123"],
    after: ["ID_523","ID_827"],
}, {
    id: "ID_827",
    before: ["ID_523"],
    after: [],
}, {
    id: "ID_999",
    before: [],
    after: [],
}];

let subgroup = 0;
let map = new Map(projects.map(p => [p.id, p]));
for (let project of projects) {
    if (project.before.length === 0 && !("subgroup" in project)) {
        let todo = new Set([project]);
        for (let project of todo) {
            project.subgroup = subgroup;
            for (let next of project.after) todo.add(map.get(next));
            for (let prev of project.before) todo.add(map.get(prev));
        }
        subgroup++;
    }
}

console.log(projects);

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

Validating Dropzone JS upon submission

I'm working on a form that utilizes dropzone.js for file upload. While I'm successfully validating all the input fields, I'm facing an issue with validating the file upload before submission. I want the submission to proceed only if a file i ...

Converting 2D pixel art into 3D coordinates with ThreeJS

Attempting to display a cube generated in ThreeJS on an HTML canvas at a specific location has been quite challenging. The location is defined in pixels, for example (100,200). Unfortunately, the process of converting these pixel values into ThreeJS coord ...

Steps to incorporate iframe into a webpage with 100% height and enable page scrollbars

Looking to seamlessly integrate an iframe into a webpage? Here are the requirements: The iframe height must adjust to fit its content, occupying 100% of available space. Hide scrollbars within the iframe, allowing the page's scrollbars to adjust acc ...

What is the best way to halt an animatePNG sequence?

I found a library that allows me to animate PNG images, you can check it out here: https://github.com/pixelmatrix/animatePNG After looking at the source code, I noticed there is a stop() method available. Can someone guide me on how to call this method in ...

Receiving a 405 error when making an API call - could the routing be misconfigured? (Using NextJS and Typescript)

Hey there, I've been working on implementing a custom email signup form that interfaces with the Beehiiv newsletter API. If you're interested, you can take a look at their API documentation here: Beehiiv API Docs Currently, my web application i ...

Issue: Angular controller fails to load during testing with Poltergeist/CapybaraExplanation: While conducting

Exploring the world of rails/angular for the first time has been an interesting journey. Currently, I am focusing on testing angular with poltergeist/capybara. While everything runs smoothly in the actual browser, it appears lifeless during testing. Despit ...

Setting up multiple RabbitMQ or other backend servers within Node configurations

As someone working in DevOps, I have encountered a situation where our developers are claiming that the Node.js software they wrote can only point to a single backend server due to Node.js limitations. This assertion seems unbelievable to me. How is it eve ...

The ineffective operation of LoopBack ACL

I have created a custom model called MyUser which inherits from the LoopBack User model. In my boot script, I created a user in the MyUser model, a custom role, and mapped that role to it. However, the ACL (Access Control List) is not working properly afte ...

Tips for preventing duplicate Java Script code within if statements

In my function, there are various statements to check the visibility of fields: isFieldVisible(node: any, field: DocumentField): boolean { if (field.tag === 'ADDR_KOMU') { let field = this.dfs_look(node.children, 'ADDR_A ...

Fixing the error message "page attempting to load scripts from an unauthenticated source"

Can you help me troubleshoot an issue on my PHP page with ad scripts? I recently switched my site from HTTP to HTTPS and now the scripts are not appearing. Here is the error I found in the dev console: Failed to load resource: the server responded with ...

Retrieving binary content from an HTML5 Canvas using base64 encoding (readAsBinaryString)

Is it possible to extract binary data from an HTML Canvas? Currently, I have the following HTML code displaying an input file and a canvas below it: <p><button id="myButton" type="button">Get Image Content</button></p> <p>In ...

Guide on utilizing Redux's Provider in React applications

I have been diving into the world of ReduxJS by closely following the documentation provided here. Towards the end of the document, it talks about utilizing the provider object. I have taken the step to wrap my App component in the provider as shown below ...

Using the same marker in React-Leaflet across different layers

Is there a way to add the same marker in multiple Layers using react-leaflet? For instance: In my restaurant search app built with react leaflet, each marker represents a different restaurant. I am looking to have a LayerControl that allows filtering by ...

Changing a "boolean bit array" to a numerical value using Typescript

Asking for help with converting a "boolean bit array" to a number: const array: boolean[] = [false, true, false, true]; // 0101 Any ideas on how to achieve the number 5 from this? Appreciate any suggestions. Thanks! ...

Utilizing Nodejs for Extracting Information from Websites

I have developed a basic web scraping tool that retrieves article titles and URLs from the following website: . However, I am encountering an issue where the scraper is only capturing 46-50 articles instead of all the available articles on the site. I ha ...

The Vue component seems to be missing the definition of $v for Vuelidate

I've been struggling to resolve this issue. The error message I am encountering pertains to a Vue component that is utilizing the Vuelidate library for form validation. Do you have any insights on what might be causing this error? Uncaught TypeError: ...

Determine future dates based on selected date and time

When a user selects a date in the datetimepicker, I want to automatically set three additional dates. The first date will be the selected date + 28 days, the second date will be selected date + 56 days, and the third date will be selected date + 84 days. I ...

Allowing Cross-Origin Resource Sharing on an Express Server hosted using Firebase Cloud Functions

Hey there, I have a simple Express setup on Firebase, shown below: import { onRequest } from 'firebase-functions/v2/https'; import express from 'express'; import bodyParser from 'body-parser'; import router from './router ...

What is the process for customizing the arrow of a <select> dropdown menu exclusively?

Here is the code for a dropdown menu: <select id="dropdown"> <option value="">Go to page...</option> <option value="http://stackoverflow.com">CSS-Tricks</option> <option valu ...

Getting Jquery to function effectively on a page loaded using ajax请求

I'm facing an issue with writing jQuery code within a page that is loaded via AJAX. When I try to implement the code on the page requested via AJAX, it doesn't work properly. However, if I remove the AJAX request and load the page directly, the j ...