What is the method for selecting the col/row or x/y coordinates for N random elements from a 2D matrix without repeating any items or coordinates?

In my dataset, which is a 2D matrix, here is an example:

data = [["a", "b", "c", "d"], ["e", "g"], ["i", "j", "k"]]

I am looking to retrieve N random (x, y) indexes without any duplicates.

Previously, I had a similar question and here is the solution I found to select 2 sets of x, y combinations:

const data = [["a", "b", "c", "d"], ["e", "g"], ["i", "j", "k"]];

function combinations(data) {
  const i11 = Math.floor(Math.random() * data.length);
  const i12 = Math.floor(Math.random() * data[i11].length);

  const dataLength = data[i11].length > 1 ? data.length : data.length - 1;

  let i21 = Math.floor(Math.random() * dataLength);
  if (i21 >= i11 && data[i11].length === 1) ++i21;

  const innerDataLength = i21 === i11 ? data[i21].length - 1 : data[i21].length;
  let i22 = Math.floor(Math.random() * innerDataLength);
  if (i21 === i11 && i22 >= i12) ++i22;
  
  return [[i11, i12], [i21, i22]];
}

console.log(combinations(data));

for (let i = 0; i < 10000; ++i) {
    const [[i11, i12], [i21, i22]] = combinations(data);
    if (i11 === i21 && i12 == i22) console.log('Test failed!');
}

Answer №1

function pickNOf(list, n) {
  // - create a new shallow array copy.
  // - does decouple the original reference, thus it
  //   prevents its further mutation by e.g. `splice`.
  list = Array.from(list);

  // - creates and returns an array of the desired length
  //   by a mapping task which constantly slices random
  //   items from the shallow array copy.
  return Array.from({ length: n }, () => list.splice(
    // - `splice` does mutate the list by removing a
    //   single item from its randomly chosen index.
    Math.floor(Math.random() * list.length), 1
  )[0]);
}

function pickNUniqueItemsFromNestedArray(arr, n) {
  // - flatten nested array structure,
  // - channel it through a `Set` in order
  //   to keep just unique values,
  // - return the result of the forwarded
  //   `pickNOf` call.
  return pickNOf([...new Set(
    arr.flat(Infinity)
  )], n);
}

const data = [
  ["a", "b", "c", "d"],
  ["e", "g"],
  ["i", "j", "k"]
];
console.log(
  "pickNUniqueItemsFromNestedArray(data, 9) ...",
  pickNUniqueItemsFromNestedArray(data, 9)
);
console.log(
  "pickNUniqueItemsFromNestedArray(data, 5) ...",
  pickNUniqueItemsFromNestedArray(data, 5)
);
console.log(
  "pickNUniqueItemsFromNestedArray(data, 3) ...",
  pickNUniqueItemsFromNestedArray(data, 3)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

Edit due to ...

Thank you it works, but i need indexes – Amine

But that's not what the question's topic doe state ... "How to pick N random elements from a 2D matrix without duplicates in javascript?" Nevertheless I will provide a second solution which utilizes the first given approach in order to fully meet the OP's requirements. – Peter Seliger

In order to meet the OP's requirements the above given approach changes slightly to ...

function pickNOf(list, n) {
  // - create a new shallow array copy.
  // - does decouple the original reference, thus it
  //   prevents its further mutation by e.g. `splice`.
  list = Array.from(list);

  // - creates and returns an array of the desired length
  //   by a mapping task which constantly slices random
  //   items from the shallow array copy.
  return Array.from({ length: n }, () => list.splice(
    // - `splice` does mutate the list by removing a
    //   single item from its randomly chosen index.
    Math.floor(Math.random() * list.length), 1
  )[0]);
}

function pickNUniqueIndexTuplesFrom2dMatrix(matrix, n) {
  // - create a flat array of any of a
  //   matrix' index coordinates/tuples.
  return pickNOf(
    matrix.flatMap((arr, rowIdx) =>
      arr.map((_, colIdx) => [rowIdx, colIdx])
    ), n
  );
}

const data = [
  ["a", "b", "c", "d"],
  ["e", "g"],
  ["i", "j", "k"]
];
console.log(
  "pickNUniqueIndexTuplesFrom2dMatrix(data, 9) ...",
  pickNUniqueIndexTuplesFrom2dMatrix(data, 9)
);
console.log(
  "pickNUniqueIndexTuplesFrom2dMatrix(data, 5) ...",
  pickNUniqueIndexTuplesFrom2dMatrix(data, 5)
);
console.log(
  "pickNUniqueIndexTuplesFrom2dMatrix(data, 3) ...",
  pickNUniqueIndexTuplesFrom2dMatrix(data, 3)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

Note

Despite or maybe even because of the misunderstanding it might become more clear that the base approach itself does not change. Which is ... pick n random items from an array without duplicates ... and ...

  • Split the main task into more specialized sub tasks. (Like demonstrated with the implementation of pickNOf which solves a single problem perfectly, thus it does not need to be refactored.)

  • The other task/s has/have to transform the input data in a way that it can be passed to the specialized task of picking n random items from an array without duplicates (which hopefully got proofed by the two different approaches each targeting a different requirement).

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

What could be causing the script to not function properly on 3D text in Unity5?

Here is the code snippet I have been working on: function OnMouseEnter() { GetComponent(Renderer).material.color = Color.grey; } function OnMouseExit() { GetComponent(Renderer).material.color = Color.white; } I've noticed that when I apply t ...

MongoDB function failing to properly return an array

I am currently exploring an efficient method to determine if each string within an array exists on MongoDB. The specific field to be queried is the 'name' field. However, I am encountering an issue when using the function below as it returns und ...

Error in Three.js: THREE.Scene is not defined as a constructor

My code won't run due to this error message: TypeError: THREE.Scene is not a constructor I've sourced the three.js file from the official GitHub repository, and these are my files: index.html <html lang="en"> <head> <meta c ...

Any tips on how to retrieve my mesh that has disappeared off the screen?

Struggling to find a way to detect when an element goes off screen, can someone provide guidance? My project utilizes WebGL along with Three.js. ...

What are the steps for examining array values using the IN operator?

I have a table with multiple arrays in each cell of the columns. COL1 COL2 row1: ('hi','hello') ('hi','hello') row2: ('hihi','below') ('pi','by') ...

Display only the initial outcome when using array_diff on an associative array

After realizing I forgot to ask the full question in a previous post, I'm glad I caught myself before asking the wrong one. So, here's the complete question: Array ( [idAsset] => 10000005 [AssetName] => HP ) Array ( [idAsset] => 1000000 ...

What are the steps to caching a message using discord.js?

In order to create a Discord bot with a command !edit [id] [new content], I have implemented the following code: if (MessageContent.startsWith('!edit ')) { if (authority >= 3) { //if false if (args.length < 3) { ...

Tips for determining the height of the entire webpage using jQuery

I attempted the following code: $(window).height(); $("#content").height(); However, it did not provide an accurate value. ...

Which element from the context menu has been selected?

We specialize in creating browser extensions for Chrome, Firefox, and Safari. Our latest project involves implementing context menus within the extensions that will appear when users right-click on any editable form element. I attempted to incorporate an e ...

Tips for ensuring elements within a modal receive immediate focus when opened in Angular 2

I am relatively new to Angular JS and I am encountering some challenges with implementing a directive in Angular 2 that can manage focusing on the modal when it is opened by clicking a button. There have been similar queries in the past, with solutions pr ...

Can a custom JavaScript variable string be inserted into a Flask variable?

TL;DR --> Can I utilize JavaScript variables to access Python variables from a Flask app within Jinja {{ }} tags? Instead of repeating similar JS code blocks for different city variables with slightly different names, like: //PTC Color Change if ({{ ...

Identifying iOS Opera Mini browsers using JavaScript

Is there a way to prevent a specific script from running on the IOS Opera Mini browser? The navigator.UserAgent method is not providing clear identification for this browser. The returned string looks something like this: Mozilla/5.0 (iPhone; CPU iPhone O ...

"Enhance user experience with the React Popover feature from Material UI

Looking for help on creating a dynamic color palette with a hover feature for the PaletteIcon. The issue I'm facing is that when I try to select a color, the palette disappears. Is there a specific property I should add to the React component or anoth ...

The css-loader is missing the required dependency peer Webpack5, causing a resolution error

Recently, I've ventured into the world of JavaScript and I'm looking to incorporate vue-audio-visual into my project. However, I encountered a perplexing error in my node console that seems unrelated. The npm error message reads as follows: code ...

Issue with resetting Knockout.JS array - unable to make it work

Hey everyone, check out the project I'm currently working on over at Github: https://github.com/joelt11753/Udacity-map In this project, I have a menu generated from a list that can be filtered using an HTML select element. Initially, all items are di ...

Tips on customizing label colors on a Donutchart using Google API

https://i.sstatic.net/Rpor0.png I am looking to change the color of 12.5 (to Green) and 25 (to red) based on the donut arc color in Google Charts. Below is the code snippet: var container = document.getElementById('chart_div'); var chart = new ...

Is there a way to modify the orientation of the bootstrap modal when it opens?

I am trying to modify the way my bootstrap reveal modal opens. I have followed the code instructions provided in this resource, but unfortunately my modal is not opening. I am using angularjs. Can someone assist me with troubleshooting the code? Here is m ...

What is the best way to access query string parameters within NextJS middleware?

In the context of NextJS middleware, I have successfully obtained the nextUrl object from the request, which includes details like the pathname. However, I am now wondering how to extract query string parameters directly within the middleware. Although I c ...

Can we disable hydration warnings for all nested children within a component in NextJS?

Note: I am currently using NextJS 14, but I suspect this issue also exists in NextJS 13. I have created a ThemeToggle component that utilizes the next-themes package. Even if I develop my own version of next-themes using React Context or another state man ...

Issue with CSS styles not linking correctly to ejs templates

I'm having trouble linking my CSS stylesheet in my project. I have the CSS file stored in a public folder with a css subfolder within it. Despite trying various methods, I can't seem to get the stylesheet to connect properly. Below is a snippet f ...