How to resolve the algorithm Sort using a custom comparator step by step in the JavaScript programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Sort using a custom comparator step by step in the JavaScript programming language

Table of Contents

Problem Statement

Sort an array (or list) of strings in order of descending length, and in ascending lexicographic order for strings of equal length. Use a sorting facility provided by the language/library, combined with your own callback comparison function.

Note:   Lexicographic order is case-insensitive.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Sort using a custom comparator step by step in the JavaScript programming language

First Source Code:

This JavaScript code sorts an array of strings based on their lengths, with ties broken alphabetically. It uses the sort method with a custom comparator function lengthSorter that:

  • Compares the lengths of two strings (b.length vs a.length).
  • If the lengths are equal, it compares the strings lexicographically (a.localeCompare(b)).

Second Source Code:

This code demonstrates more generic sorting functions in JavaScript:

  • It defines several helper functions for comparing, mapping, and flipping functions.
  • It defines sorting functions for:
    • Sort by length ascending, then alphabetically ascending
    • Sort by length descending, then alphabetically ascending
    • Sort by population ascending
    • Sort by population descending
  • It demonstrates using these functions to sort arrays of strings and objects.

Third Source Code:

This code uses Haskell to define generic sorting functions and apply them to a list of strings:

  • It defines functions for comparing values based on length and alphabetical order.
  • It defines a function mappendOrd to merge ordering results.
  • It defines a function sortBy to sort a list based on a comparison function.
  • It defines a function flip to flip the order of arguments in a function.
  • It defines a function lengthThenAZ to sort by length ascending and then alphabetically ascending.
  • It defines a function descLengthThenAZ to sort by length descending and then alphabetically ascending.
  • It uses these functions to sort a list of strings in various orders.

Source code in the javascript programming language

function lengthSorter(a, b) {
  var result = b.length - a.length;
  if (result == 0)
    result = a.localeCompare(b);
  return result;
}

var test = ["Here", "are", "some", "sample", "strings", "to", "be", "sorted"];
test.sort(lengthSorter);
alert( test.join(' ') );                      // strings sample sorted Here some are be to


(function () {
    'use strict';

    // GENERIC FUNCTIONS FOR COMPARISONS

    // Ordering :: ( LT | EQ | GT ) | ( -1 | 0 | 1 )

    // compare :: a -> a -> Ordering
    var compare = function (a, b) {
        return a < b ? -1 : a > b ? 1 : 0;
    };

    // mappendOrdering :: Ordering -> Ordering -> Ordering
    var mappendOrdering = function (a, b) {
        return a !== 0 ? a : b;
    };

    // on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
    var on = function (f, g) {
        return function (a, b) {
            return f(g(a), g(b));
        };
    };

    // flip :: (a -> b -> c) -> b -> a -> c
    var flip = function (f) {
        return function (a, b) {
            return f.apply(null, [b, a]);
        };
    };

    // arrayCopy :: [a] -> [a]
    var arrayCopy = function (xs) {
        return xs.slice(0);
    };

    // show :: a -> String
    var show = function (x) {
        return JSON.stringify(x, null, 2);
    };

    // TEST
    var xs = ['Shanghai', 'Karachi', 'Beijing', 'Sao Paulo', 'Dhaka', 'Delhi', 'Lagos'];

    var rs = [{
        name: 'Shanghai',
        pop: 24.2
    }, {
        name: 'Karachi',
        pop: 23.5
    }, {
        name: 'Beijing',
        pop: 21.5
    }, {
        name: 'Sao Paulo',
        pop: 24.2
    }, {
        name: 'Dhaka',
        pop: 17.0
    }, {
        name: 'Delhi',
        pop: 16.8
    }, {
        name: 'Lagos',
        pop: 16.1
    }];

    // population :: Dictionary -> Num
    var population = function (x) {
        return x.pop;
    };

    // length :: [a] -> Int
    var length = function (xs) {
        return xs.length;
    };

    // toLower :: String -> String
    var toLower = function (s) {
        return s.toLowerCase();
    };

    // lengthThenAZ :: String -> String -> ( -1 | 0 | 1)
    var lengthThenAZ = function (a, b) {
        return mappendOrdering(
            on(compare, length)(a, b),
            on(compare, toLower)(a, b)
        );
    };

    // descLengthThenAZ :: String -> String -> ( -1 | 0 | 1)
    var descLengthThenAZ = function (a, b) {
        return mappendOrdering(
            on(flip(compare), length)(a, b),
            on(compare, toLower)(a, b)
        );
    };

    return show({
        default: arrayCopy(xs)
            .sort(compare),

        descendingDefault: arrayCopy(xs)
            .sort(flip(compare)),

        byLengthThenAZ: arrayCopy(xs)
            .sort(lengthThenAZ),

        byDescendingLengthThenZA: arrayCopy(xs)
            .sort(flip(lengthThenAZ)),

        byDescendingLengthThenAZ: arrayCopy(xs)
            .sort(descLengthThenAZ),

        byPopulation: arrayCopy(rs)
            .sort(on(compare, population)),

        byDescendingPopulation: arrayCopy(rs)
            .sort(on(flip(compare), population))
    });
})();


(() => {
    'use strict';

    // main :: IO ()
    const main = () => {
        const
            lengthThenAZ = mappendOrd(
                comparing(length),
                comparing(toLower)
            ),
            descLengthThenAZ = mappendOrd(
                flip(comparing(length)),
                comparing(toLower)
            );

        console.log(
            apList(apList([sortBy])([
                lengthThenAZ,
                descLengthThenAZ
            ]))([
                [
                    "Here", "are", "some", "sample",
                    "strings", "to", "be", "sorted"
                ]
            ]).map(unlines).join('\n\n')
        );
    };

    // GENERIC FUNCTIONS ----------------------------------

    // apList (<*>) :: [a -> b] -> [a] -> [b]
    const apList = fs => xs =>
        // The application of each of a list of functions,
        // to each of a list of values.
        fs.flatMap(
            f => xs.flatMap(x => [f(x)])
        );

    // comparing :: (a -> b) -> (a -> a -> Ordering)
    const comparing = f =>
        (x, y) => {
            const
                a = f(x),
                b = f(y);
            return a < b ? -1 : (a > b ? 1 : 0);
        };

    // flip :: (a -> b -> c) -> b -> a -> c
    const flip = f =>
        1 < f.length ? (
            (a, b) => f(b, a)
        ) : (x => y => f(y)(x));

    // length :: [a] -> Int
    const length = xs =>
        (Array.isArray(xs) || 'string' === typeof xs) ? (
            xs.length
        ) : Infinity;

    // mappendOrd (<>) :: Ordering -> Ordering -> Ordering
    const mappendOrd = (a, b) => a !== 0 ? a : b;

    // sortBy :: (a -> a -> Ordering) -> [a] -> [a]
    const sortBy = f => xs =>
        xs.slice()
        .sort(f);

    // toLower :: String -> String
    const toLower = s => s.toLocaleLowerCase();

    // unlines :: [String] -> String
    const unlines = xs => xs.join('\n');

    // MAIN ---
    return main();
})();


  

You may also check:How to resolve the algorithm Check output device is a terminal step by step in the REXX programming language
You may also check:How to resolve the algorithm Create a two-dimensional array at runtime step by step in the C# programming language
You may also check:How to resolve the algorithm Sum to 100 step by step in the PureBasic programming language
You may also check:How to resolve the algorithm Generate lower case ASCII alphabet step by step in the Lang programming language
You may also check:How to resolve the algorithm FizzBuzz step by step in the VTL-2 programming language