All files / libs/algorithms/src sort.ts

100% Statements 127/127
100% Branches 29/29
100% Functions 6/6
100% Lines 127/127

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 1281x 9x 9x 2x 2x 7x 9x 6x 6x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 8x 8x 8x 8x 64x 64x 35x 35x 35x 35x 64x 8x 8x 1x 1x 8x 1x 1x 1x 1x 1x 1x 1x 1x 8x 8x 8x 8x 8x 8x 35x 35x 35x 35x 8x 8x 8x 1x 1x 1x 1x 1x 1x 17x 17x 17x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 16x 16x 1x 1x 1x 1x 16x 15x 15x 15x 15x 15x 16x 16x 8x 8x 8x 12x 12x 12x 12x 12x 8x 8x 8x 1x 1x 1x 1x 1x 8x 17x 17x 17x 1x 1x 15x 8x 8x 7x 7x 7x 7x 7x 7x  
const sortCompare = <Element, Key extends keyof Element>(a: Element, b: Element, key: Key): number => {
    // eslint-disable-next-line security/detect-object-injection
    if (a[key] > b[key]) {
        return 1;
    }
    // eslint-disable-next-line security/detect-object-injection
    if (a[key] < b[key]) {
        return -1;
    }
    return 0;
};
 
export const by = <Element, Key extends keyof Element>(array: Element[], key: Key): Element[] => {
    // eslint-disable-next-line security/detect-object-injection,no-nested-ternary
    return Array.from(array).sort((a: Element, b: Element) => sortCompare<Element, Key>(a, b, key));
};
 
// @src https://github.com/kutyel/typescript-algorithms/blob/master/src/bubbleSort/index.ts
export const bubble = <Element>(array: Element[]): Element[] => {
    const sorted = Array.from(array);
 
    // eslint-disable-next-line no-loops/no-loops, no-constant-condition
    while (true) {
        let swapped = false;
 
        // eslint-disable-next-line no-loops/no-loops
        for (let index = 0; index < sorted.length - 1; index++) {
            // eslint-disable-next-line security/detect-object-injection
            if (sorted[index] > sorted[index + 1]) {
                // eslint-disable-next-line security/detect-object-injection
                [sorted[index], sorted[index + 1]] = [sorted[index + 1], sorted[index]];
                swapped = true;
            }
        }
 
        if (!swapped) {
            break;
        }
    }
 
    return sorted;
};
 
export const insertion = <Element>(array: Element[]): Element[] => {
    const sorted = array;
    // eslint-disable-next-line no-loops/no-loops
    for (let index = 1; index < sorted.length; index++) {
        // eslint-disable-next-line security/detect-object-injection
        const currentItem: Element = sorted[index];
        let currentLeftIndex: number = index - 1;
 
        // eslint-disable-next-line no-loops/no-loops, security/detect-object-injection
        while (currentLeftIndex >= 0 && sorted[currentLeftIndex] > currentItem) {
            // eslint-disable-next-line security/detect-object-injection
            sorted[currentLeftIndex + 1] = sorted[currentLeftIndex];
            currentLeftIndex -= 1;
        }
 
        sorted[currentLeftIndex + 1] = currentItem;
    }
 
    return sorted;
};
 
// @see https://www.jesuisundev.com/comprendre-les-algorithmes-de-tri-en-7-minutes/
export const merge = <Element>(array: Element[]): Element[] => {
    const sorted = array;
 
    if (sorted.length > 1) {
        const middleIndex = Math.floor(sorted.length / 2);
        const leftSide = sorted.slice(0, middleIndex);
        const rightSide = sorted.slice(middleIndex);
 
        merge(leftSide);
        merge(rightSide);
 
        let leftIndex = 0;
        let rightIndex = 0;
        let globalIndex = 0;
 
        // eslint-disable-next-line no-loops/no-loops
        while (leftIndex < leftSide.length && rightIndex < rightSide.length) {
            // eslint-disable-next-line security/detect-object-injection
            if (leftSide[leftIndex] < rightSide[rightIndex]) {
                // eslint-disable-next-line security/detect-object-injection
                sorted[globalIndex] = leftSide[leftIndex];
                // eslint-disable-next-line no-plusplus
                leftIndex += 1;
            } else {
                // eslint-disable-next-line security/detect-object-injection
                sorted[globalIndex] = rightSide[rightIndex];
                // eslint-disable-next-line no-plusplus
                rightIndex += 1;
            }
            globalIndex += 1;
        }
 
        // eslint-disable-next-line no-loops/no-loops
        while (leftIndex < leftSide.length) {
            // eslint-disable-next-line security/detect-object-injection
            sorted[globalIndex] = leftSide[leftIndex];
            leftIndex += 1;
            globalIndex += 1;
        }
 
        // eslint-disable-next-line no-loops/no-loops
        while (rightIndex < rightSide.length) {
            // eslint-disable-next-line security/detect-object-injection
            sorted[globalIndex] = rightSide[rightIndex];
            rightIndex += 1;
            globalIndex += 1;
        }
    }
 
    return sorted;
};
 
export const quick = <Element>(array: Element[]): Element[] => {
    if (array.length <= 1) {
        return array;
    }
    const pivot = array.pop() as Element;
    const smallerValues = array.filter((item) => item < pivot);
    const biggerValues = array.filter((item) => item > pivot);
 
    return [...quick(smallerValues), pivot, ...quick(biggerValues)];
};