Fluctuating Values in Array Distribution

I have a set of users and products that I need to distribute, for example:

The number of values in the array can vary each time - it could be one value one time and three values another time.

It is important that each user receives a unique product with no duplicates.

Currently, my code shuffles the array and assigns ten random products to each user:

var users = ["user1", "user2", "user3"];

var products = ["p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10","p11", "p12", "p13", "p14", "p15", "p16", "p17", "p18", "p19", "p20", "p21", "p22", "p23", "p24", "p25", "p26", "p27", "p28", "p29", "p30"];

function shuffle(array) {
var currentIndex = array.length, temporaryValue, randomIndex;

while (0 != currentIndex) {

  randomIndex = Math.floor(Math.random() * currentIndex);
  currentIndex -= 1;

  temporaryValue = array[currentIndex];
  array[currentIndex] = array[randomIndex];
  array[randomIndex] = temporaryValue;
}

return array;
}

i = 0;
while (i < users.length) { 
    newArray = (shuffle(products)).slice(0, 10)
    console.log(users[i++] + ' products: ' + newArray);
}

Output:

user1 products: p5,p6,p13,p2,p19,p22,p8,p20,p27,p28
user2 products: p6,p30,p22,p9,p25,p2,p7,p17,p19,p10
user3 products: p20,p25,p23,p4,p28,p9,p12,p14,p21,p17

Answer №1

The challenge presented by this task lies in the balancing act of distributing products to users in a way that ensures some overlap while maintaining fairness and uniqueness. Achieving this efficiently requires additional code.

Here is an outline of the algorithm's approach:

  • Every product will be allocated at least once;
  • Roughly 20% of the products will be distributed twice;
  • No user will receive the same product multiple times;
  • All users will be assigned almost the same number of products, with a maximum difference of one;
  • If any users end up with one less product, they are selected randomly;
  • The sequence in which each user receives their products is randomized.

function shuffled(arr) {
  // Creates a new array without altering the original
  arr = arr.slice();
  var i = arr.length;
  while (i) {
    var j = Math.floor(Math.random() * i--);
    [ arr[i], arr[j] ] = [ arr[j], arr[i] ];
  }
  return arr;
};

function distribute(products, users) {
    // Handling edge cases:
    if (users.length === 0) return {};
    if (users.length === 1) return { [users[0]]: shuffled(products) };    

    // Distributing around 20% of products twice
    var distributeCount = Math.ceil(products.length * 1.2); 
    
    // Structure to store assignments: keys are usernames, 
    //   values are sets of products
    var possessions = users.reduce( (acc, user) => 
        Object.assign(acc, { [user]: new Set() }), {} );

    var usersLeft = shuffled(users);
    while (usersLeft.length < distributeCount)
        usersLeft = usersLeft.concat(usersLeft);
    usersLeft.length = distributeCount;
    
    var productsLeft = shuffled(products).concat(shuffled(products)); 

    // Assigning products to users
    while (usersLeft.length) {
        product = productsLeft.pop();
        user = usersLeft.pop();
        if (possessions[user].has(product)) {
            if (usersLeft.length) {
                [ user, usersLeft[usersLeft.length-1] ] = 
                    [ usersLeft[usersLeft.length-1], user ]; 
            } else {
                do {
                    product = productsLeft.pop();
                    if (!product) throw "Could not find product for user";
                } while (possessions[user].has(product));
            }
        }
        possessions[user].add(product);
    }
    // Converting Sets into Arrays
    for (user in possessions) possessions[user] = [...possessions[user]];
    return possessions;
}

var users = ["user1", "user2", "user3"];
var products = ["p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10","p11", 
                "p12", "p13", "p14", "p15", "p16", "p17", "p18", "p19", "p20", "p21", 
                "p22", "p23", "p24", "p25", "p26", "p27", "p28", "p29", "p30"];

var result = distribute(products, users);

console.log(result);

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

Issue with splitting a JavaScript function in JQuery within the Wordpress platform can cause errors

My split function seems to be causing an error, as shown in this console error image. There is a hidden input field within the PHP file: <input class="file-id" name="_file-id" type="hidden" value="<?php echo esc_attr($file_ids); ?>" /> I hav ...

Check if the data-indices of several div elements are in sequential order using a jQuery function

Is there a way to implement a function in jQuery-ui that checks the order of div elements with data-index when a submit button is pressed? I have set up a sortable feature using jQuery-ui, allowing users to rearrange the order of the divs. Here is an exam ...

Can one look through a div to the one beneath it by moving the cursor?

Hey there! I have a unique question for you. I've been trying to achieve a specific effect where two divs are stacked on top of each other, and the content of the lower div is only revealed in a certain area around the cursor. Is it possible to make o ...

Utilizing Rails' JSON response with Ember.js

This is a sample serializer class TestSerializer < ActiveModel::Serializer attributes :post def post @post = user.joins(:post).select("user.name as name,post.content as content").where("user_id = ?",object.id) end end I'm try ...

Transform a hash into an array in Perl without the need for an additional variable

Is it possible to convert a hash to an array in Perl without using an additional variable? The following code works as expected, but it utilizes another variable (@arr): perl -wlae '%hash=(name=>"linus", forename=>"torvalds "); @arr=%hash; prin ...

Incorporate a secondary (auxiliary) class into ReactJS

Looking to create a helper class similar to this: export default class A { constructor() { console.log(1); } test() { console.log(2); } } and utilize it within a component like so: import React, { Component } from "react"; import A from ...

Guide to including objects into your project without the need for babel through the use of CDN

I'm struggling with getting my Vue code to transpile properly due to some issues. I have resorted to loading Vue and other packages directly using CDN links, like this: <script src="https://cdnjs.cloudflare.com/ajax/libs/survey-vue/1.8.33/surv ...

Issue with Express.js res.append function: Headers cannot be set after they have already been sent

I encountered an issue in my express project where I tried to set multiple cookies using "res.append" in the same request, but I kept getting an error saying "Error: Can't set headers after they are sent.". Can someone help me identify the problem and ...

Locate a piece of text with jQuery and enclose it within a specified container

Check out this code <form method="get" name="form_delivery"> Pick the country where you want your delivery<br> <select name="deliverymethod"> <option value="0" selected="selected">Choose a country / region</option> ...

Executing an external HTTP request within an ExpressJS middleware prior to rendering the response

Currently, I am facing a challenge while trying to utilize Express middleware for a login request. The default route generates an external URL that redirects to /login?code={login-code}. This URL triggers an external HTTP request to obtain the user_id and ...

Slight Misalignment of Elements

I am attempting to align two corners of an element so that they perfectly match the corners of another element. In simpler terms, I am aiming to synchronize the corners of one element with those of another element. Below is the code snippet: ... When y ...

Is there another way to implement this method without having to convert snapshotChanges() into a promise?

When trying to retrieve cartIdFire, it is returning as undefined since the snapshot method is returning an observable. Is there a way to get cartIdFire without converting the snapshot method into a promise? Any workaround for this situation? private asyn ...

Is there a way to include a lockfile in a docker container as an optional step?

I am attempting to create a docker image that can optionally incorporate a yarn or npm lockfile during the build process. I want to include it explicitly, but also ensure that the build does not fail if the lockfile is missing. The goal is to respect dete ...

I am attempting to retrieve the aria-expanded value using JavaScript, however, I keep receiving an "undefined" response

I'm attempting to dynamically change the class of a <span> element based on the value of the attribute aria-expanded. However, I am encountering an issue where it returns "undefined" instead of the expected value of true or false. Below is the ...

"Combining MySQL queries with PDO and designing dynamic web pages with

I am currently developing an application using the Twig templating library. My PDO statement returns the following array: Array ( [0] => Array ( [id] => 1 [artist] => Dena ...

Implementing a two-column infinite scrolling feature using ISCroll

I am looking to incorporate multi-column infinite scrolling using IScroll infinite scrolling. I want the content of my HTML to appear as follows: <ul> <li>A</li> <li>B</li> <li>C</li> <li>D</li> ...

Eliminate the presence of core-js in the nextjs bundle

Currently, I am tackling the challenge of minimizing bundle sizes in my Next.js project. One particular aspect that caught my attention is the inclusion of a core-js bundle for polyfills. This adds an extra 50KB to the size of the main bundle, which I aim ...

What steps are involved in developing a jQuery Validator function to enforce username restrictions?

Currently, I have implemented a method to enforce strong passwords like this: $.validator.addMethod('goodPassword', function(value, element){ return this.optional(element) || value.length >= 6 && /\d/.test(val ...

Implementing a loading animation effect using AJAX that requires a loop delay and sleep functionality

My jquery ui dialog is loaded via ajax with a partial view from the server. Initially, the dialog opens as a dialog-ajax-loader and then animates/grows to fit the content once the call returns. The issue arises when the dialog content gets cached or the a ...

Ways to verify if a user is authenticated without relying on request.session

I am currently developing a web application using Express, Docker, and following a Three-layered architecture. In my app, I store user login information in a session and have blogposts as a key resource. To retrieve the blogpostId from the database in the ...