Traversing an array of objects in TypeScript and appending to a separate array if not already present

I have been given an array containing objects in the following format:

export interface Part {
  workOrder?: string;
  task?: string;
  partNumber?: string;
  qty?: number;
  image?: string;
  name?: string;
}

My goal is to loop through each object in the array and create a new array based on this interface:

export interface WorkOrder {
  workOrder?: string;
  tasks?: Array<string>;
}

This is what my code currently looks like:

let partList: Part[] = [ 
  { workOrder: "W1", task: "do something", ... },
  { workOrder: "W1", task: "something else", ... },
  { workOrder: "W2", task: "do something", ... },
  { workOrder: "W2", task: "something else", ... }
];

let workOrders: WorkOrder[] = [];

I aim to populate the workOrders array with the workOrder and task from each Part. If a workOrder has already been added, I want to append the additional task to the existing tasks array under that workOrder.

The final output should resemble this:

workOrders = [ 
  { workOrder: "W1", tasks: [ "do something", "something else" ] },
  { workOrder: "W2", tasks: [ "do something", "something else" ] }
];

Currently, I am using multiple for loops and checking the .indexOf() method for certain arrays, but I believe there must be a more efficient approach.

Answer №1

let workOrdersList = [];

partList.forEach(element => {
  if (!workOrdersList.find(order => order.workOrder === element.workOrder)) {
      workOrdersList.push({ workOrder: element.workOrder, tasks: [element.task] 
  });
  } else {
      workOrdersList.find(order => order.workOrder === 
      element.workOrder).tasks.push(element.task);
  }
})

Utilize the find method to check if an element is included in the list, if it's present then add the task to existing work order or create a new one.

Answer №2

Utilize the reduce method.

Take a look at this code snippet

let dataList = [
  { ID: "001", description: "item one" },
  { ID: "002", description: "second item" },
  { ID: "003", description: "another item" },
  { ID: "004", description: "final item" }
];

let items = dataList.reduce((acc, curr) => {
  var currentItem = acc.find((element) => element.ID === curr.ID);
  if (currentItem)
    currentItem.details.push(curr.description);
  else
    acc.push({ ID: curr.ID, details: [curr.description]});
  
  return acc;
}, []);

console.log(items);
.as-console-wrapper {
  max-height: 100% !important
}

Additional Resources

Answer №3

To aggregate data based on the workOrder, you can utilize the reduce method as shown below:

var result = partList
    .reduce<{ [name: string]: WorkOrder }>((map, r) => {
        let existing = map[r.workOrder];
        if (existing) {
            existing.tasks.push(r.task);
        } else {
            map[r.workOrder] = {
                tasks: [r.task],
                workOrder: r.workOrder
            };
        }
        return map;
    }, {});

var asArray = Object.values(result)

If data grouping is a common requirement, consider creating a reusable group function to simplify the process:

function group<T>(data: T[]) {
    return {
        byKey(keyGetter: (e: T) => string) {
            return {
                createGroup<TResult>(ctor: (e: T) => TResult) {
                    return {
                        addToGroup(adder: (e: T, c: TResult) => void) {
                            var result = data
                                .reduce<{ [name: string]: TResult }>((map, r) => {
                                    let key = keyGetter(r)
                                    let existing = map[key];
                                    if (existing) {
                                        adder(r, existing);
                                    } else {
                                        map[key] = ctor(r);
                                    }
                                    return map;
                                }, {});

                            return Object.values(result)
                        }
                    }
                }
            }
        }
    }
}
let finalResult = group(partList)
    .byKey(x => x.workOrder)
    .createGroup(x => <WorkOrder>{ tasks: [x.task], workOrder: x.workOrder })
    .addToGroup((e, c) => c.tasks.push(e.task));

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

React DnD now enables dragging an entire list of cards instead of just a single card

Implementing react DnD in my react Project has been challenging. In the render method, I have defined a variable called Populate that generates a list of cards as shown below: render() { var isDragging = this.props.isDragging; var connect ...

Prevent certain dates from being selected in a designated input field

I am facing an issue with disabling certain array dates for a specific input field in a datepicker calendar. Even though I have included the script to exclude those dates, they are not getting disabled for that particular input field. html <input cla ...

Exploring the Usage of sessionStorage within the <template> Tag in Vue.js

Is it possible to access sessionStorage in the script section of a Vuejs component like this? <template> {sessionStorage} </template> Whenever I try to call it this way, I consistently receive the error message "cannot read property &apo ...

Uncover the issue with the examination: solving the enigma of the ancient wizards' sect

I am attempting to crack this enigma in Java, revolving around an elderly man sustained by his cult members who share their life force with him. The code provided must adhere to the specified rules, but there seems to be an error during testing. public cla ...

jQuery load() function triggers unexpected error in jQuery plugin

Here is the current structure of my page: <body> <div id="menuBar"> </div> <canvas id="myCanvas" width="700" height="700" style="border:1px solid #000000;"></canvas> </body> <script src="../Scripts/jQuery.mazeBo ...

What is the best way to hear an event emitted by a component?

I am trying to listen for an event in Chrome DevTools Vue, but I'm not sure how to target it. For a Root event, I typically use: this.$root.$on("note_id", (note_id) => (this.note_id = note_id)); But how do I address an event that origina ...

Promise not being properly returned by io.emit

io.emit('runPython', FutureValue().then(function(value) { console.log(value); //returns 15692 return value; // socket sends: 42["runPython",{}] })); Despite seeing the value 15692 in the console, I am encountering an issue where the promise ...

Receiving an array of data from a SOAP service using PHP

Hi there, I'm a beginner in PHP and I'm slowly learning the basics. I recently encountered an issue where I am unable to receive an Array from a SOAP server. Here's a snippet of my code: class cUSER { public $LOGIN; public $ ...

Guide to redirecting to another page with parameters in React

After successfully integrating Stripe with React and processing a payment, I am trying to redirect to another page. await stripe .confirmCardPayment(CLIENT_SECRET, { payment_method: { card: elements.getElement(CardElement), ...

What is the best way to connect these functions in a sequence using promises?

A new software has been developed to extract data from an online t-shirt store and then organize the product information into a CSV file. The software consists of 3 scraping functions and 1 function for writing the data. I'm currently facing challen ...

Sending Disabled Form Field Input Value in Angular 2 POST Request

I'm working on a form with an email field that I want to populate using interpolation. However, I also want to prevent users from changing the email address once it's displayed. To achieve this, I tried adding the disabled attribute to the input ...

The functionality of the Bootstrap 4 Carousel featuring multiple items is experiencing malfunctions

I'm encountering an issue with my Bootstrap 4 card carousel. When the next or prev buttons are clicked, there is a strange transition effect. Additionally, in the mobile version, the buttons do not work properly. It seems that when the card slides to ...

Automatically switch tabs upon pressing/scanning the Return key (using PHP, MySQL, and JavaScript)

Seeking assistance to resolve an ongoing issue that has been troubling me for the past few weeks. I am maintaining a basic web-based database to keep track of product serial numbers leaving our warehouse. The system is secure behind our firewall, so I&apo ...

I'm trying to find the location of the server.js file in Node

Currently, I am diving into a book that delves into the integration of nodejs and backbonejs. It covers the foundational aspects that serve as the building blocks for understanding. (...) To kick things off, execute the command 'npm install express& ...

Having trouble implementing pagination for news-api in Vue.js2?

I am currently working on implementing a basic pagination feature in my Vue component specifically for the newsapi.org API. While my initial API call in the created hook is functioning as expected, I am encountering difficulties navigating to different pa ...

How can I combine multiple textures from mtlLoader and objLoader in three.js?

I have the files .mtl, .obj, and several .jpg textures. I have been attempting to use different textures in the export loader OBJ, and while I can see my object on the scene, it appears as a black color. Can anyone spot what might be incorrect or missing ...

Encountered a Node.js build error related to a Java module

Encountering issues while attempting to integrate the JAVA module into my NodeJS application on Ubuntu: NodeJS: v6.2.0 NPM: 3.8.9 Node-gyp: v3.3.1 Python: 2.7.12 GCC: 5.4.0 Despite having all the required dependencies, I consistently face errors when ...

Is it possible to perform ECDH Key Exchange using public keys of varying lengths?

Currently, I am working on implementing an ECDH key-exchange using the P-384 curve. While other curves could be used, I believe the implementations should be fairly similar in nature. The goal is for the Client (Javascript) and Server(Java) to establish a ...

Failure to initiate JavaScript function with onClick event

I've been struggling with a simple issue related to calling a javascript function. After spending several hours trying to debug it on my own, I'm reaching out for help in the hopes that a fresh perspective can assist me. Here is the snippet of c ...

Tips for creating a two-tier selection filter system

I'm having an issue with this code. My objective is to create two filters for this table. The select element with id="myInput" should determine which rows appear in the table and apply the first filter. Here is the JavaScript code: function myFunctio ...