https://sintheta.nexus/blog/feed.xml

Joys of Javascript

2024-09-12

Not familiar w/ JavaScript? Here's your crash course!

// arrow syntax => assigns anonymous functions
const binarySearch = (arr, target) =>
{
    // sort() takes such an anoymous sorting function
    const sortedArr = arr.sort((a, b) => a - b);

    // `reduce((acc, curVal, curIdx, array) => { /* */ }, { initialAccValue });`
    // Note: while `_` denotes a placeholder, it's a legal variable name!
    // using it twice gives a 'SyntaxError: Duplicate parameter name'
    // (you could actually use `_` and `__` as variables here...)
    return sortedArr.reduce((acc, _, __, array) =>
    {
        // see `initialAccValue` specified after `{}`
        if (acc.found) return acc;
  
        const { low, high } = acc; // destructuring assignment

        // `{}`     in place object creation
        // `...`    spread operator
        // `...acc` spread acc properties into new object (shallow copy)
        // `found: false`   property overriding, found overriden to be false

        if (low > high) return { ...acc, found: false };

        // the usual recursive binary search logic follows
        // we're continuously returning the `acc` object
        // using property overriding to modify it
  
        const mid = Math.floor((low + high) / 2);
      
        if (array[mid] === target) {
          return { ...acc, found: true, index: mid };
        } else if (array[mid] < target) {
          return { ...acc, low: mid + 1 };
        } else {
          return { ...acc, high: mid - 1 };
        }
    }, { low: 0, high: sortedArr.length - 1, found: false, index: -1 });
};

// each iteration of reduce() the `acc` is returned for 'further processing'

const numbers = [34, 7, 23, 32, 5, 62];
const target = 23;

const result = binarySearch(numbers, target);

if (result.found) {
    console.log(`Target ${target} found at index ${result.index}`);
} else {
    console.log(`Target ${target} not found`);
}

// and since this isn't enough fun yet:
// reduce's callback function takes _ANY_ number of parameters
// undefined parameters are simply left undefined
// this is JS being flexible (the function is _not_ overloaded)

function example(a, b, c)
{
    console.log('a: ', a);
    console.log('b: ', b);
    console.log('c: ', c);
}
example(1);

// you cannot only provide b, but can simulate this effect
// (of course we can simply reuse the function name 'example' cause...)

function example(a, b)
{
    console.log('a: ', a);
    console.log('b: ', b);
}
example(undefined, 2);

// 'undefined' is a special value representing value abscence

// back to reduce:
//  a) illustration

const numbers2 = [2, 4, 6, 8];
const result2  = numbers2.reduce((acc, curVal, curIdx, arr) =>
{
    console.log(`acc: ${acc} val: ${curVal} idx: ${curIdx} arr: ${arr}`);
    return acc;
}, 0);

//  b) leaving last two parameters undefined
const sum = numbers2.reduce((acc, curVal) =>
{
    return acc + curVal;
}, 0);

console.log(sum); // 2 + 4 + 6 + 8

Output:

Target 23 found at index 2
a:  1
b:  undefined
a:  undefined
b:  2
acc: 0 val: 2 idx: 0 arr: 2,4,6,8
acc: 0 val: 4 idx: 1 arr: 2,4,6,8
acc: 0 val: 6 idx: 2 arr: 2,4,6,8
acc: 0 val: 8 idx: 3 arr: 2,4,6,8
20