Skip to content
Advertisement

Shuffle array of N letters and take M of them

I have an X array of objects "letter":"frequency" and i’m trying to build a new Y array from the previous one made of frequency-times letters (for each present in X ary). Then my purpose is to shuffle Y ary and take just the z-first elements from that. n is an argument passed to the function

exports.listLetters = (n) => {
return new Promise((resolve, reject) => {
    const sql = 'SELECT * FROM letters';
    db.all(sql, [], (err, rows) => {
        if (err) {
            reject(err);
            return;
        }
        if (rows == undefined) {
            resolve({ error: "Errors with retrieving letters. " })
        } else {

            const letters = rows.map((e) => ({ letter: e.letter, frequency: e.frequency }));const letters = rows.map((e) => ({ letter: e.letter, frequency: e.frequency }));
            let freqLetters = [];
            for (let letter in letters) {
                for (let i = 0; i <= letter.frequency * 100; i++) {
                    freqLetters.push(letter);
                }
            };

            shuffleArray(freqLetters);
            freqLetters.slice(0, n);

            resolve(freqLetters);

Why this algorithm doesn’t work? Shuffle function is:

function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
}

Advertisement

Answer

The big problem that make your code doesn’t work is you can’t directly use for in to loop through the array contains array. You doesn’t define the rows and letter so I create one for showing purpose.

You missed the property name, I would suugest you to use forEach as an alternative option.

Also, slice doesn’t change on the original array, it creates a copy, so you should define another array.

The slice() method returns a shallow copy of a portion of an array into a new array object selected from start to end

let rows = [{
    letter: 'word',
    frequency: 5
  },
  {
    letter: 'yes',
    frequency: 4
  },
  {
    letter: 'no',
    frequency: 3
  }
]
let n = 10
const letters = rows.map((e) => ({
  letter: e.letter,
  frequency: e.frequency
}));

let freqLetters = [];

letters.forEach(function(arr) {
  for (let i = 0; i <= arr.frequency * 100; i++)
    freqLetters.push(arr.letter);


})

shuffleArray(freqLetters);
let finalarray = freqLetters.slice(0, n)
console.log(finalarray)
function shuffleArray(array) {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
}
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement