Utilizing the reduce method to transform an array containing nested arrays into a different structure

I'm having trouble figuring out how to restructure the array below.

I attempted to utilize the reduce function in JavaScript but unfortunately, I couldn't make it work.

So far, this is the function I have come up with:

var comb = []
var setEle = []
var setEle = []
input.forEach(a => {
  a.productVariations.forEach(element => {
    if (comb.indexOf(element.variationName) === -1) {
      comb.push(element.variationName)

      let group = element.variationOptions.reduce((r, a) => {
        r['variationName'] = element.variationName
        r['variationOptions'] = [...(r[a.name] || []), a]

        return r
      }, {})

      group['linked'] = []
      setEle.push(group)
    }
  })

})

How can I reorganize the array as shown below and successfully use my reduce function?

var input = [
  {
    companyName: 'ABC',
    productVariations: [
      {
        variationName: 'Colour',
        variationOptions: [
          {
            name: 'Blue'
          },
          {
            name: 'Red'
          }
        ]
      },
      {
        variationName: 'Pattern',
        variationOptions: [
          {
            name: 'Bold'
          },
          {
            name: 'Spotted'
          }
        ]
      }
    ]
  },
  {
    companyName: 'BBC',
    productVariations: [
      {
        variationName: 'Colour',
        variationOptions: [
          {
            name: 'Blue'
          },
          {
            name: 'Red'
          },
          {
            name: 'Purple '
          }
        ]
      }
    ]
  }
]

This is the desired output format:

var output = [
  {
    variationName: 'Colour',
    variationOptions: [
      {
        name: 'Blue'
      },
      {
        name: 'Purple'
      },
      {
        name: 'Red'
      },
    ],
    linked: [
      {
        companyName: 'BBC'
      },
      {
        companyName: 'ABC'
      }
    ]
  },
  {
    variationName: 'Pattern',
    variationOptions: [
      {
        name: 'Bold'
      },
      {
        name: 'Spotted'
      },
    ],
    linked: [
      {
        companyName: 'ABC',
      }
    ]
  }
]

In the output array, the variationOptions are grouped by variationName and the relevant companyName is added to the linked child array.

Answer №1

To achieve unique items, utilize the forEach method to loop through and construct an object with values from companyNames and variationOptions, stored as a Set. Subsequently, recreate the array by leveraging the map function on the previous sets.

const merge = (arr) => {
  const result = {};
  arr.forEach(({ companyName, productVariations }) => {
    productVariations.forEach(({ variationName, variationOptions }) => {
      if (!result[variationName]) {
        result[variationName] = { options: new Set(), links: new Set() };
      }
      result[variationName].links.add(companyName);
      variationOptions.forEach(({ name }) =>
        result[variationName].options.add(name)
      );
    });
  });
  return Object.entries(result).map(([variationName, {options, links}]) => ({
    variationName,
    variationOptions: [...options].map((name) => ({ name })),
    linked: [...links].map((companyName) => ({ companyName })),
  }));
};

var data = [
  {
    companyName: "ABC",
    productVariations: [
      {
        variationName: "Colour",
        variationOptions: [
          {
            name: "Blue",
          },
          {
            name: "Red",
          },
        ],
      },
      {
        variationName: "Pattern",
        variationOptions: [
          {
            name: "Bold",
          },
          {
            name: "Spotted",
          },
        ],
      },
    ],
  },
  {
    companyName: "BBC",
    productVariations: [
      {
        variationName: "Colour",
        variationOptions: [
          {
            name: "Blue",
          },
          {
            name: "Red",
          },
          {
            name: "Purple ",
          },
        ],
      },
    ],
  },
];

console.log(merge(data));

Answer №2

Here is a solution that can be implemented:


const combineVariations = input.flatMap(obj => obj.productVariations.map(x => ({...x, linked:[{companyName: obj.companyName}]})))
const finalResult = combineVariations.reduce((acc, curr) => {
    const existingObj = acc.find(x => x.variationName === curr.variationName)
    if(existingObj) {
        const uniqueOptions = [...new Set([...curr.variationOptions, ...existingObj.variationOptions].map(x => x.name))]
        existingObj.variationOptions = uniqueOptions.map(x => ({name: x}));
        existingObj.linked.push(...curr.linked)
    } else {
        acc.push(curr)
    }
    return acc;
}, [])

Answer №3

Here is an example:

def process_data(data):
    processed_data = []

    for item in data:
        existing_item = next((x for x in processed_data if x['key'] == item['key']), None)

        if existing_item:
            existing_item['values'].extend(item['values'])
        else:
            processed_data.append({
                'key': item['key'],
                'values': item['values']
            })

    return processed_data

input_data = [
    {'key': 'A', 'values': [1, 2, 3]},
    {'key': 'B', 'values': [4, 5]},
    {'key': 'A', 'values': [6, 7]}
]

output_data = process_data(input_data)
print(output_data)
<pre id="output" />

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

Remove Request (MongoDB, express, handlebars)

Struggling with implementing a delete request in my application. I have a database filled with reviews that I manipulate through my app. Currently, I'm attempting to create a function that will remove a document from the database and then redirect th ...

The feature for automatically hiding other dropdowns when one is open is not functioning properly

Trying to finalize a mega menu that almost works. I need help with closing all other open mega menus when a user clicks on one. Check out the JavaScript code snippet I've written below. The mega menu currently toggles correctly, but it doesn't h ...

Use the sed utility to modify a specific value within a .spec file

Is there a way to modify the value in the .spec file using sed? I need to change the $nmatch value of build to something different, like "build1.1". { "files": [ { "aql": { "items.find": { "repo&qu ...

Converting a PHP timestamp to a jQuery-compatible format

Can someone help me find the equivalent function in jQuery that will give me a time format similar to this: date( 'Y-m-d\TH:i:sP'); //the output is like this. 2013-10-30T18:10:28+01:00 I am looking for this specific format in jQuery to use ...

Exclude specific outcomes within a nested document in MongoDB

I have a situation where I need to query a list of items and only retrieve the ones that correspond to a specific ID in the provider_cost_dict. Essentially, if I input providerId = 10001, then only the items with a matching entry in the provider_cost_dict ...

Tips for opening a variety of links in new tabs with unique popup buttons

Currently, I am facing a challenge where I need to use a button to trigger an ajax HTML popup and also navigate to a link simultaneously. The issue is that there are multiple buttons on the page, each needing to open different links. Any assistance would b ...

Find the most recent date in a file and display the line associated with it

I am working with a document named Application.txt that consists of multiple columns and rows as shown below: ApplNo DocsURL DocDate 4782 www…. 7/28/2003 4782 www…. 11/23/2008 4782 www…. 3/24/2012 5010 www…. 4/5/2003 5010 ww ...

Best practices for handling errors beyond network problems when using the fetch() function

I am facing a situation where the route of my fetch() call can result in two different responses, each requiring a different action. However, I have noticed that the catch() method only handles network errors as far as I know. Currently, my code looks lik ...

Encountering an issue where an error message indicates that a variable previously declared is now undefined

Currently, I am working on developing a small test application to enhance my coding skills. However, I have encountered a roadblock while attempting to display dummy information from a mongodb database that I have set up. I have tried various solutions bu ...

Encountering a 405 Method not Allowed error in C# Azure when trying to make a POST request using

After following a tutorial, I successfully set up my Azure backend. https://example.com/tutorial I then installed Postman for the first time and configured it with: {"username": "user123", "password": "securepass"} Content-Type: application/json Howev ...

If the user is not authenticated, Node.js will redirect them to the login page

I've integrated the node-login module for user login on my website. Once a user logs in, the dashboard.html page is rendered: app.get('/', function(req, res){ // Check if the user's credentials are stored in a cookie // if (req.coo ...

Deconstructing numerous JsonObject and JsonArray structures

I am facing some challenges while working with multiple jsonobjects specifically "posts" and "attachments". Although I attempted to utilize separate lines and another for loop for the attachments jsonObject, it was not successful. String postInfo = j ...

Exploring effective testing approaches for C++ plugins in Node.js

When working on Node JS, I have experience creating native C++ modules. However, my testing approach typically involves writing tests for these modules in Javascript. I am curious if this is an effective test strategy or if there are more optimal ways to ...

Implementing a 'Load More' button for a list in Vue.js

I am currently working on adding a load more button to my code. While I could achieve this using JavaScript, I am facing difficulties implementing it in Vue.js. Here is the Vue code I have been working with. I attempted to target the element with the compa ...

Load texture programmatically instead of using MTL files

I've successfully loaded an OBJ file and linked it with an MTL to provide a texture. However, I'm struggling to specify which texture should be associated with the model directly in the code; it seems that the texture only appears on the model if ...

Is there a way to dispatch an event from one Angular ui-router view to another view?

In order to change the login button to display "logged in as xxx" after authentication, I have structured my page into three views: header, content, footer. The login button is located in the header view. Upon clicking login, it transitions to the "app.log ...

What strategies can be used to effectively perform a mongo db search that accommodates misspelled terms?

If I search for "wolrd," I would like documents containing "world" to be included in the results. ...

Is it possible in Swift to determine the type of an Element in an Array and then utilize it to define the generic type argument?

In my coding project, I've defined a protocol called APIRequest which includes an associated type called ResponseType and a decode function. While the example provided here is not exhaustive, it covers the essential components needed for this discussi ...

Turn off the use of to_json and from_json functions when the data types of member variables do not align with nlohmann's json library

Utilizing nlohmann's single header json library to serialize a custom class is proving to be challenging. The goal is to make this class compatible with various types, including boost's multiprecision types. However, certain types, like boost&apo ...

Ensuring uniqueness in an array using Typescript: allowing only one instance of a value

Is there a simple method to restrict an array to only contain one true value? For instance, if I have the following types: array: { value: boolean; label: string; }[]; I want to make sure that within this array, only one value can be set to t ...