0

I have a mapping function that iterates over an array of items. I already sliced the data to select only a small handful of data to display. However now I also want the mapping to select random items from the array.

const randomStocks = Math.floor(Math.random() * buckets.stock_count);

Here is my mapping function:

{bucket.stock_list.slice(0, 4).map((stock, index) =>
    {return(
            <Chip key={index} label={stock} />
            )}
)}

Where and how can I add my randomStocks in my mapping function while respecting the slicing of data?

andres
  • 1,558
  • 7
  • 24
  • 62

2 Answers2

2

If your array is not immensely large, then a practical solution is to first shuffle your array randomly, and then to slice as you already do.

For shuffling you can use one of the answers provided in How can I shuffle an array:

function shuffle(a) {
    var j, x, i;
    for (i = a.length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        x = a[i];
        a[i] = a[j];
        a[j] = x;
    }
    return a;
} 

So then your code can be:

{
    shuffle(Array.from(bucket.stock_list)).slice(0, 4).map((stock, index) => {
        return(
            <Chip key={index} label={stock} />
        )
    })
}

The call to Array.from is only needed if you don't want to mutate the stock list itself, and keep its original order untouched.

trincot
  • 317,000
  • 35
  • 244
  • 286
  • Thank you for showing me how too, is there any way to get the shuffle not work during state changes? – andres Mar 12 '21 at 23:22
  • I don't understand that question. If you don't want to shuffle, then don't call that function? – trincot Mar 12 '21 at 23:27
  • Maybe you want to call shuffle only once (and persist it), and not have it run in the same function as where you render? – trincot Mar 12 '21 at 23:32
  • Thank you, basically the shuffle happens every time a state changes on the page (as expected). I forgot that would happen. I will research about how to persist it, thank you very much! – andres Mar 13 '21 at 00:24
2

You can use following random integer generator from Math.Random():

const ITEMS_LIMIT = 4;

function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min) + min); //The maximum is exclusive and the minimum is inclusive
}

const randomStocks = getRandomInt(0, buckets.stock_count - ITEMS_LIMIT);

You can then do

{
   bucket.stock_list.slice(randomStocks, randomStocks+ ITEMS_LIMIT).map((stock, index) => {
      return <Chip key={index} label={stock} />
   })
}
T J
  • 42,762
  • 13
  • 83
  • 138
  • 1
    The second argument of `slice` is not a length. If this is fixed, it will return a random subsection of the array, which only makes the first selected item random. All the other selected elements are determined by that choice. – trincot Mar 12 '21 at 22:31