How to select N unique random values that appear exactly once in an existing array with TypeScript

1 Answer

0 votes
/*
    Goal:
    - Select N random values that appear exactly once in the array.
    - The array includes duplicates, but only values with frequency = 1
      are eligible for selection.

    Approach:
    1. Count frequencies using a Map<number, number>.
    2. Collect values that appear exactly once.
    3. Shuffle the unique list using Fisher–Yates.
    4. Take the first N values.
    5. Return them and print them.

    Notes:
    - Uses modern TypeScript (ES6+).
    - Uses expressive, structured functions.
*/

//---------------------------------------------------------------
// Build a frequency map: value -> count
//---------------------------------------------------------------
function buildFrequencyMap(data: number[]): Map<number, number> {
    const freq: Map<number, number> = new Map<number, number>();

    for (const value of data) {
        const currentCount: number = freq.get(value) ?? 0;
        freq.set(value, currentCount + 1);
    }

    return freq;
}

//---------------------------------------------------------------
// Collect values that appear exactly once
//---------------------------------------------------------------
function collectGloballyUniqueValues(
    data: number[],
    freq: Map<number, number>
): number[] {

    const unique: number[] = [];

    for (const value of data) {
        const count: number | undefined = freq.get(value);
        if (count === 1) {
            unique.push(value);
        }
    }

    return unique;
}

//---------------------------------------------------------------
// Randomly select N values from the unique list
//---------------------------------------------------------------
function selectRandomUnique(unique: number[], N: number): number[] {
    let count: number = unique.length;

    if (N > count) {
        N = count; // clamp
    }

    // Shuffle using Fisher–Yates
    const temp: number[] = [...unique];

    for (let i: number = temp.length - 1; i > 0; i--) {
        const j: number = Math.floor(Math.random() * (i + 1));
        const swap: number = temp[i];
        temp[i] = temp[j];
        temp[j] = swap;
    }

    return temp.slice(0, N);
}

//---------------------------------------------------------------
// Print helper
//---------------------------------------------------------------
function printList(list: number[]): void {
    console.log(list.join(" "));
}

//---------------------------------------------------------------
// Main program
//---------------------------------------------------------------
(function main(): void {

    // Example array with duplicates
    const data: number[] = [
        5, 12, 5, 19, 5, 33, 19, 5, 8, 8, 8, 59, 61, 17, 3, 5, 3, 74, 83, 90, 3, 1
    ];

    // Step 1: Build frequency map
    const freq: Map<number, number> = buildFrequencyMap(data);

    // Step 2: Collect values that appear exactly once
    const uniqueValues: number[] = collectGloballyUniqueValues(data, freq);

    // Step 3: Choose how many unique random values to select
    const N: number = 5;

    // Step 4: Select N random unique values
    const randomSelection: number[] = selectRandomUnique(uniqueValues, N);

    // Step 5: Print results
    console.log("Values that appear exactly once:");
    printList(uniqueValues);

    console.log("\nRandom selection (" + N + " values):");
    printList(randomSelection);

})();


/*
run:

Values that appear exactly once:
12 33 59 61 17 74 83 90 1

Random selection (5 values):
12 33 1 74 17

*/

 



answered Sep 13 by avibootz

Related questions

...