Creating diverse options using attribute-value pairs

I am in need of creating an array that contains all possible combinations of attribute values.

Here is an example of my attributes/values object:

let attr = {
    color: ['red', 'green', 'blue'],
    sizes: ['sm', 'md', 'lg'],
    material: ['cotton', 'wool']
}

The goal is to generate an array containing all potential combinations like the following:


color  |  size  |  material
-----------------------------
red      sm        cotton
red      sm        wool
red      md        cotton
red      md        wool
red      lg        cotton
red      lg        wool
blue     sm        cotton
blue     sm        wool
blue     md        cotton
blue     md        wool
blue     lg        cotton
blue     lg        wool
green    sm        cotton
green    sm        wool
green    md        cotton
green    md        wool
green    lg        cotton
green    lg        wool

The number of attribute types and values can vary (minimum one). How do I accomplish this task?

This is the current code snippet I have been working on:

// keys = ['color', 'sizes', 'material']
// attributes object as shown above

for (let i = 0; i < keys.length; i++) {
    let key = keys[i];
    let values = attr[key];

    // iterate through each value
    for (let j = 0; j < values.length; j++) {

        // for each value, loop over all keys
        for (let k = 0; k < keys.length; k++) {
            if (i === k) {
                continue;
            }

            for (let l = 0; l < values.length; l++) {

                // What should I do next?
                // Unsure if I am on the right track here?

            }

        }

    }

}

Answer №1

My approach involved two steps. Firstly, I extracted an array of arrays from the attributes object (such as

[['red', 'green', 'blue'], ['sm', ...], ...]
). After that, I recursively computed the product of those arrays and then organized them back into objects with the correct keys.

let attributes = {
    color:    ['red', 'green', 'blue'],
    sizes:    ['sm', 'md', 'lg'],
    material: ['cotton', 'wool']
};

let getProducts = (arrays) => {
  if (arrays.length === 0) {
    return [[]];
  }

  let results = [];

  getProducts(arrays.slice(1)).forEach((product) => {
    arrays[0].forEach((value) => {
      results.push([value].concat(product));
    });
  });

  return results;
};

let getAllCombinations = (attributes) => {
  let attributeNames = Object.keys(attributes);

  let attributeValues = attributeNames.map((name) => attributes[name]);

  return getProducts(attributeValues).map((product) => {
    obj = {};
    attributeNames.forEach((name, i) => {
      obj[name] = product[i];
    });
    return obj;
  });
};

console.log(getAllCombinations(attributes));

// Output:
// [ { color: 'red', sizes: 'sm', material: 'cotton' },
//   { color: 'green', sizes: 'sm', material: 'cotton' },
//   { color: 'blue', sizes: 'sm', material: 'cotton' },
//   { color: 'red', sizes: 'md', material: 'cotton' },
//   { color: 'green', sizes: 'md', material: 'cotton' },
//   { color: 'blue', sizes: 'md', material: 'cotton' },
//   { color: 'red', sizes: 'lg', material: 'cotton' },
//   { color: 'green', sizes: 'lg', material: 'cotton' },
//   { color: 'blue', sizes: 'lg', material: 'cotton' },
//   { color: 'red', sizes: 'sm', material: 'wool' },
//   { color: 'green', sizes: 'sm', material: 'wool' },
//   { color: 'blue', sizes: 'sm', material: 'wool' },
//   { color: 'red', sizes: 'md', material: 'wool' },
//   { color: 'green', sizes: 'md', material: 'wool' },
//   { color: 'blue', sizes: 'md', material: 'wool' },
//   { color: 'red', sizes: 'lg', material: 'wool' },
//   { color: 'green', sizes: 'lg', material: 'wool' },
//   { color: 'blue', sizes: 'lg', material: 'wool' } ]

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

Tips for showing the value in the subsequent stage of a multi-step form

Assistance is required for the query below: Is there a way to display the input field value from one step to the next in multistep forms? Similar to how Microsoft login shows the email in the next step as depicted in the image below: ...

When the margin-left changes, SVG begins to flicker and shake in a marquee effect

I've been experimenting with a marquee effect using vanilla JS. The effect is working, but I'm encountering some shaking issues with SVG and images as they move. <div class="marquee"> <h1>Nepal <svg version="1.1&qu ...

How can I pass props from a custom _app.js file to the <Navbar> component in Next.js?

How do I go about passing props to a Navbar component that will be included under the Head component? Although I successfully passed props in the index.js page using getServerSideProps, it seems to not work properly in the _app.js file. import ".. ...

The Vue property or method is unrecognized when utilizing the non-minified version

When I attempted to display the name 'John' using an inline template in a simple Vue example, I encountered the following error message: [Vue warn]: Property or method "name" is not defined on the instance but referenced during render. ...

Link JSON filters to specific JSON nodes on the map

I have data representing nodes and links for a force directed graph. The links can have different numbers of connections between them, such as one, two, or three links: {"nodes": [{"id": "Michael Scott", "type": "boss"} ,{"id": "Jim Halpert", "t ...

Using Three.js to import and cast rays on a .obj model created in Blender

I have successfully imported a 3D terrain using Blender and the OBJLoader in Three.js. In addition, I have created a mesh (highlighted in yellow in the image below) that I want to follow the mouse cursor while it hovers over the terrain. I have attempted t ...

Harnessing the power of JavaScript functions to display an image when clicked

Looking for help with making an image appear when clicking on one of three images? Despite trying different approaches, the desired result is still not achieved. I'm aware of using if else statements but exploring other methods. Any insights on what m ...

Capturing groups in Javascript Regex not populating back-references correctly

Here's an interesting situation (or maybe not so uncommon): I'm trying to extract two specific capturing groups using JavaScript regex. The first group should consist of one or more digits (0-9), while the second group should consist of one or mo ...

Tips for transforming a nested array of arrays into a string separated by commas

Currently, I have an object that contains 2 nested arrays. Both of these arrays are array of arrays and I am looking to combine their values into a comma-separated string. I am exploring options in JavaScript, jQuery, or linq.js to accomplish this task. Wh ...

Steps for filling an HTML table within a dynamically loaded DIV

I have a container in my HTML page where I dynamically load other pages using the jQuery.load() function. One of the pages requires me to populate a table from the database just after/before it loads. How can I trigger a JavaScript function to execute righ ...

I am interested in using an image upload box that includes a hidden input field. However, I have encountered issues with the functionality when the input field is hidden. Does anyone have any suggestions on how

I have limited experience and need some assistance with resolving this particular issue. I am looking to create an image upload box that works when clicked on the input field. Thank you in advance. function readURL(input) { if (input.files && ...

Typescript MUI Autocomplete: Can you specify the parameter type of the PaperComponents function?

If you use MUI's Autocomplete, there is a property called PaperCompomponent that allows you to pass your own react component. This property is a function with properties as a parameter, which can then be used to pass on to your custom component. In T ...

Enable the submission of the form with a combo of Shift key and Enter

When using a simple form that posts to a basic PHP script, I encountered an issue where if someone is typing quickly and accidentally holds down the Shift key while pressing "Enter," a barrage of PHP error messages appears. Is there a way to allow Shift + ...

What are some ways to integrate the features of ctype.h into JavaScript?

How can glibc's ctype.h be effectively translated into JavaScript? While I believe it is possible, I am struggling to locate the tables and bitshifting operations used in the C source code. What are the best techniques to employ in this situation? isa ...

What is the process for sending a POST Request to Ghostbin using Node.JS?

I'm attempting to make a POST request to Ghostbin using Node.JS and the request NPM module. Below is the code I have been utilizing: First Try: reqest.post({ url: "https://ghostbin.com/paste/new", text: "test post" }, function (err, res, body) ...

The absence of parameters in the Express.js middleware object

const application = express(); let routerInstance = require('express').Router({mergeParams: true}); const payloadMiddlewareFunction = (request, response, next) => { console.log('A:', request.params); const {params, query} = reque ...

Why are the elements not found by their id when I check them, even though they were created dynamically using an ajax-generated form with php-inserted values through a

How can I prepopulate form fields displayed in a modal view using jQuery after retrieving the form HTML with an AJAX query? I am trying to set the values through a JavaScript function that retrieves PHP-generated values via document.getElementById. However ...

Steps to Utilize Google Apps Script from a Website

I've been on a mission to find the solution to my problem. I have a basic web page with HTML/CSS/JS. What I want is for users to visit the page and immediately have it call up a Google script I created, which will pull information from a spreadsheet a ...

Encountering an issue with ReactJS + Redux where the error message states: "Error in prop type: The Right-hand side of 'instanceof' cannot be called"

Currently working on a web app project in React with Redux for global state management. A puzzling issue has arisen - we're receiving warnings in the browser console. How can we resolve this? It seems related to prop types declaration, but the soluti ...

Intermittent issue with Webdriver executeScript failing to detect dynamically created elements

It has taken me quite a while to come to terms with this, and I am still facing difficulties. My goal is to access dynamically generated elements on a web page using JavaScript injection through Selenium WebDriver. For instance: String hasclass = js.exec ...