How can I efficiently map an array based on multiple other arrays in JavaScript/TypeScript using ES6(7) without nested loops?

I am dealing with 2 arrays:

const history = [
   { type: 'change', old: 1, new: 2 },
   { type: 'change', old: 3, new: 4 },
];

const contents = [
   { id: 1, info: 'infor1' },
   { id: 2, info: 'infor2' },
   { id: 3, info: 'infor3' },
   { id: 4, info: 'infor4' },
];

The resulting array should be:

const detailHistory = [
   { type: 'change', old: { id: 1, info: 'infor1' }, new: { id: 2, info: 'infor2' } },
   { type: 'change', old: { id: 3, info: 'infor3' }, new: { id: 4, info: 'infor4' } },
];

I need help in creating detailHistory without using a nested loop with history and contents

Answer №1

To start, create a Map for the contents, allowing you to easily retrieve objects by their id. From there, the task involves mapping the objects in the history:

const history = [
   { type: 'change', old: 1, new: 2 },
   { type: 'change', old: 3, new: 4 },
];

const contents = [
   { id: 1, info: 'infor1' },
   { id: 2, info: 'infor2' },
   { id: 3, info: 'infor3' },
   { id: 4, info: 'infor4' },
];

const contentsMap = new Map(contents.map(o => [o.id, o]));
const result = history.map(o => ({
    ...o,
    old: contentsMap.get(o.old),
    new: contentsMap.get(o.new)
}));

console.log(result);

It's important to note that when assigning values to old and new, they will reference the original objects in the contents array rather than creating copies. If this behavior is not desired, consider making (shallow) copies of the objects at the time they are mapped into the result:

const history = [
   { type: 'change', old: 1, new: 2 },
   { type: 'change', old: 3, new: 4 },
];

const contents = [
   { id: 1, info: 'infor1' },
   { id: 2, info: 'infor2' },
   { id: 3, info: 'infor3' },
   { id: 4, info: 'infor4' },
];

const contentsMap = new Map(contents.map(o => [o.id, o]));
const result = history.map(o => ({
    ...o,
    old: {...contentsMap.get(o.old)},
    new: {...contentsMap.get(o.new)}
}));

console.log(result);

Answer №2

Here is a potential solution for your problem:

const history = [
  { type: "change", old: 1, new: 2 },
  { type: "change", old: 3, new: 4 }
];

const contents = [
  { id: 1, info: "infor1" },
  { id: 2, info: "infor2" },
  { id: 3, info: "infor3" },
  { id: 4, info: "infor4" }
];

let detailHistory = history.map((e, i) => {
  e.old = contents.find((element) => element.id === e.old);
  e.new = contents.find((element) => element.id === e.new);
  return e;
});
console.log(detailHistory);

Alternatively, you could utilize Object.keys() in the following manner:

const history = [
  { type: "change", old: 1, new: 2 },
  { type: "change", old: 3, new: 4 }
];

const contents = [
  { id: 1, info: "infor1" },
  { id: 2, info: "infor2" },
  { id: 3, info: "infor3" },
  { id: 4, info: "infor4" }
];

let detailHistory = history.map((e, i) => {
  Object.keys(e).map((key) => {
    e[key] = contents.find((element) => element.id === e[key])
      ? contents.find((element) => element.id === e[key])
      : e[key];
  });
  return e;
});
console.log(detailHistory);

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

Unable to forward page in EJS

Hey everyone, I've been struggling with trying to redirect to a page in EJS, but it just doesn't seem to work for some reason. Here's my code: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

Managing nested Angular repeats with counter

In the previous section of my document, I have a presentation layer that effectively organizes information within a shopping cart. This arrangement functions perfectly fine. At the lower portion, I employ the following code to generate form variables whic ...

developing a dynamic map with javascript

In the image provided, my concept is for it to initially be without a green tint. However, when the user hovers over specific areas, they would turn green and become clickable links. There are multiple areas in the image, with this being just one example. ...

What is the best way to integrate a button within a datatable cell to display additional details in a popup window?

I am seeking help with datatable.js. I would like to insert a button inside the cells of the datatable columns to expand and display the detailed content of each cell. When I click on the red button, a popup modal should appear showing the full list of con ...

Adding a loader to the specific button that has been clicked can be achieved by following these steps:

I am currently in the process of building an e-commerce platform website and I'm looking to implement a feature where users can add products to their cart with just a click of a button. However, before the product is added to the cart, I want to disp ...

Most effective method for automatically scrolling down upon page load

Below is the code snippet that I am using: <script type="text/javascript"> window.onload = function () { window.scrollBy(0, 100); } </script> The purpose of this code is to scroll down after the page has fi ...

Guide to downloading a CSV file directly from a webpage built with vue.js

Delving into the world of vue.js, I find myself pondering over how to incorporate a download link in my webpage for a CSV file stored locally. In my component Template.vue, I have the following structure: <a :href="item.loc" download> {{item.title ...

Adjusting Image Size According to Window Resize?

My current issue involves having four images displayed side by side. When the window size is adjusted or viewed on a smaller device, the layout shifts to a line jump (with three images in a row and the fourth one below). What I actually want is for all fou ...

Top guidelines for validating inherited props within React applications

Exploring a component called <Section /> which requires 3 props to function: color size title The color and size props are used for styling purposes, while the title prop is passed down to its child component <SectionTitle />. Here's an ...

Ensuring Vue.js correctly re-renders an array item

In my vue.js 2 project, I am working with an array that has the following structure: data() { return { ports: [ { id: 1, name: "example", "age": 10, scores: [ {index: 1, value: 100}, {index: 2, value: 200} ]}, { id: 2, ...

The Jquery .clone() function presents issues in Internet Explorer and Chrome browsers, failing to perform as expected

I need to duplicate an HTML control and then add it to another control. Here is the code I have written: ko.bindingHandlers.multiFileUpload = { init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { va ...

Link scripts can sometimes cause issues with node.js

Greetings! I have successfully created a client-side SPA using vanilla-router. However, my Node.js server sometimes encounters an error when attempting to load a linked script. Uncaught SyntaxError: Unexpected token '<' This error only oc ...

Choosing the relevant kendo row on two different pages

I am facing a situation where I have a Kendo grid displayed on a dashboard page. Whenever a user selects a row in this grid, I need to load the same row in another Kendo grid on a separate ticket page to showcase the details of that particular ticket. The ...

Enabling or disabling a button dynamically in Ionic based on a conditional statement

I am looking to dynamically enable or disable buttons based on specific conditions. The data is retrieved from Firebase, and depending on the data, I will either enable or disable the button. For example, if a user passes the First Quiz, I want to enable ...

How can I declare CSS variables in Next.js components' module.css just like in global CSS?

When writing CSS in our global file, we often define variables and styles like this: :root{ --orange:#e67e22; --black:#333; --light-color:#777; --border:.1rem solid rgba(0,0,0,.2); --box-shadow:0 .5rem 1rem rgba(0,0,0,.1); } *{ mar ...

I can't understand why my server is displaying an error on the browser stating "This site can't be reached ERR_UNSAFE_PORT" while it is functioning flawlessly on the terminal

I have created an index.html file, along with index.js and server.js. In the server.js file, I have included the following code: const express = require("express"); const path = require("path" ); const app = express(); app.use(" ...

No definition found for state

Currently, I am facing an issue while trying to fetch data from an API, set it on my State, and display that state in a table. The problem arises because the render method is called first, causing my state to be undefined which leads to this specific issue ...

I am currently working on a website that offers different themes, and I am attempting to update the iframe to reflect the selected theme on the site

I'm feeling lost on how to accomplish this task. Despite my efforts, I have been unable to find a solution so far. Perhaps utilizing javascript might be the key here, yet I am uncertain about integrating it into the existing script that I use for modi ...

VueJS error: Trying to access properties of undefined object ('$refs') is unsuccessful

Parent Component: ... <v-stepper-step :rules="[()=>isValid(1)]" > MyStep </v-stepper-step> <v-stepper-content> <Mytag ref="MyReference" /> </v-stepper-content> ... methods: { isValid(number){ ...

Auth0 Angular - No routes found to match

I recently set up an angular application and integrated it with Auth0 by following two helpful tutorials: https://auth0.com/docs/quickstart/spa/angular2/01-login https://auth0.com/docs/quickstart/spa/angular2/02-calling-an-api Here is a brief overview o ...