Skip to content

Some helpful tips, tricks, good practices and ready-made solutions in Javascript / Typescript

Notifications You must be signed in to change notification settings

karpinski1994/JS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

40 Commits
 
 

Repository files navigation

JS

Some helpful tips, tricks, good practices and ready-made solutions in Javascript / Typescript

List of javascript useful practical tricks and patterns


  1. Arrays
    1. Reduce
      1. Sum values
      2. Count the average
      3. Calculate several values at once
      4. Calculate items
      5. Find min and max
      6. Find min and max
      7. Calculate items
      8. Parse array of objects into an object
      9. Filter out data from a nested structure
    2. ReduceRight
      1. Reverse a string
    3. Map
      1. Creating ranges
      2. Extracting data from objects
      3. Parsing to float
      4. Create an alphabet
    4. Flat
      1. Process nested arrays
      2. Extract data from nested API
    5. FlatMap
    6. Filter
      1. Filter out falsy values
  2. Functional programming
    1. Currying
      1. Summing numbers
      2. Adding vat
    2. Partial application
      1. Summing numbers
    3. Recursion
      1. Decrease and conquer - searching
      2. Numbers exponential

 

Arrays

Reduce

 

Sum values of an array

 

const numbers = [29.76, 41.85, 46.5];

const sum = numbers.reduce((total, amount) => total + amount);

sum // 118.11

// Other way

const sum = (acc, value) => acc + value;
const mySum = numbers.reduce(sum, 0);

 

Count the average of array

 

const numbers = [29.76, 41.85, 46.5];

const average = (array) => array.reduce((a, b) => a + b) / array.length;

const avg = average(numbers)
avg // 39.37


// 2nd way
const avg = array.reduce(sum, 0) / array.length;

// 3rd way
const avg2 = (sum, val, id, arr) => {
  sum += val;
  return id === arr.length - 1 ? sum / arr.length : sum;
};

Calculating several values at once

 

// Object
const average = arr => {
const sumCount = arr.reduce(
  (acc, val) => ({sum: val + acc, count acc.count + 1}),
  {sum: 0, count: 0});

  return sumCount.sum / sumCount.count;
}

// Array
const average = arr => {
const sumCount = arr.reduce(
  (acc, val) => ({sum: acc[0] + val, count acc[1] + 1}),
  [0, 0]);

  return sumCount[0] / sumCount[1]
}

Calculate itams in an array

 

const brands = ['suzuki', 'suzuki', 'mercedes', 'audi', 'mercedes'];

const brandsCount = arr.reduce(
    (acc, val) => ({ ...acc, [val]: acc[val] ? acc[val] + 1 : 1}),
    {}
  );

Result

{
  audi: 1
  mercedes: 2
  suzuki: 2
}

Find min and max in array

 

const nums = [1, 2, 3, 4, 5, 6, 7, 8];

const [min, max] = nums.reduce(
  (acc, cur) => [Math.min(acc[0], cur), Math.max(acc[1], cur)],
  [Infinity, 0]
);

// min: 1
// max: 8

   

Sum even and odd numbers in one go

 

const numbers = [1, 2, 3, 4, 5];

const evenOddSum = array => array.reduce((acc, cur, id) => (acc[id & 1] += cur,acc), [0,0])

const sum = evenOddSum(numbers);
sum // [9, 6]

 

Transform array of objects into object storing children objects by id

 

const objectsArr = [
  {
    id: 1,
    name: 'Peter',
    proffesion: 'plumber',
  },
  {
    id: 2,
    name: 'Mark',
    proffesion: 'baker',
  },
  {
    id: 3,
    name: 'Greg',
    proffesion: 'firefighter',
  },
];

Solution

const objectsByIdArr = objectsArr.reduce(
  (acc, curr) => ({ ...acc, [curr.id]: curr }),
  {}
);

Result

objectsByIdArr {
  '1': { id: 1, name: 'Peter', proffesion: 'plumber' },
  '2': { id: 2, name: 'Mark', proffesion: 'baker' },
  '3': { id: 3, name: 'Greg', proffesion: 'firefighter' }
}

 

 

Filter out data from nested structure

 

const data = [
  {a: 'pig', b: 'dog', c: ['apple','grape']}, 
  {a: 'cat', b: 'seal', c: ['banana','orange']}, 
  {a: 'fish', b: 'cow', c: ['coconut','pineapple']}
];

Filter out fruits

Solution

const fruitsOnly = data.reduce((totalFruits, obj) => {
  obj.fruits.forEach((f) => totalFruits.push(f))
  return totalFruits;
}, [])

Result

fruitsOnly:  [
  'apple',     'grape',
  'banana',    'orange',
  'blueberry', 'raspberry',
  'coconut',   'pineapple'
]

 

reduceRight

 

Reverse string
const reverseString = str => str.split('').reduceRight((x, y) => x + y, '');

Map

 

Ranges
const range = (from, to, including = true) => {
  const scope = including ? to - from + 1 : to - from - 1;
  return Array(scope)
    .fill(0)
    .map((_, id) => (including ? from + id : from + id + 1));
};

 

Extracting data from objects
const cities = [
  {name: 'New York', long:40.7128, lat: 74.0060},
  {name: 'Tokyo', long:25.2048, lat: 55.2708},
  {name: 'Krakow', long:50.0647, lat: 19.9450},
]

const avgLong = average(cities.map(city => city.long))
const avgLat = average(cities.map(city => city.lat))

 

Parse float
const numbers = ['4.2332', '12.221', '2131.4367'].map(parseFloat);

// Doesnt work with parseInt! which takes more args

 

Create alphabet
const ALPHABET = range('A'.charCodeAt(), 'Z'.charCodeAt()).map(code => String.fromCharCode(code));

Flat

 

Process nested arrays

const numbers = [1, 2, [[3, (4)[(5, 6)]][(7, 8)]]];

const oneLevelDeep = numbers.flat(1);

const twoLevelsDeep = numbers.flat(2);

const flattedTotally = numbers.flat(Infinity);


 

Extract participants from nested api structure
const apiAnswer = [
  {
    id: 122232,
    name: 'John Doe',
    groups: [
      {
        groupId: 121221,
        groupName: 'Doplphins',
        participants: [{ participantId: 3846864, name: 'Max' }],
      },
    ],
  },
  {
    id: 122233,
    name: 'Marry Cohen',
    groups: [
      {
        groupId: 232131,
        groupName: 'Alaska Team',
        participants: [{ participantId: 2644487, name: 'Merry' }],
      },
    ],
  },
  {
    id: 122234,
    name: 'Christine Malone',
    groups: [
      {
        groupId: 12121221,
        groupName: 'Tigers',
        participants: [
          {
            participantId: 50720006,
            name: 'Harry',
          },
          {
            participantId: 4899911,
            name: 'Barry',
          },
          {
            participantId: 4899966,
            name: 'Lissie',
          },
        ],
      },
    ],
  },
];


Solution

  apiAnswer.map(x => x.groups)
  .flat()
  .map(y => y.participants)
  .flat()

Result

[
  {
    name: 'Max',
    participantId: 3846864,
  },
  {
    name: 'Merry',
    participantId: 2644487,
  },
  {
    name: 'Harry',
    participantId: 50720006,
  },
  {
    name: 'Barry',
    participantId: 4899911,
  },
  {
    name: 'Lissie',
    participantId: 4899966,
  },
]

FlatMap

 

Same example as above
apiAnswer
  .flatMap(x => x.groups)
  .flatMap(y => y.participants)

Filter

Filter out falsy values

[1, 2, 3, 0].filter(Boolean)
// result [1, 2, 3]

 

Every

Make none using every (function returning true only when non of elements pass the predicate)

const none = (arr, fn) => arr.every(v => !fn(v));

 

Functional programming

Fire function once
const once = (once) => {
  let done = false;
  return (...args) => {
    if (!done) {
      done = true;
      once(...args);
    }
  };
};
Another way
const once = (fn) => {
  return (...args) => {
    fn && fn(...args);
    fn = null;
  };
};
Fire function once and after (for ex. warning)
const onceAndAfter = (once, after) => {
  let done = false;
  return (...args) => {
    if (!done) {
      done = true;
      once(...args);
    } else {
      after(...args);
    }
  };
};

Factorial by range

 

const factorialByRange = n => range(1, n).reduce((x, y) => x * y, 1); 

Memoization

 

Fibonacci

let cache = [];

const fibo = (n) => {
  if (cache[n] === undefined) {
    if (n === 0) {
      cache[0] = 0;
    } else if (n === 1) {
      cache[1] = 1;
    } else {
      cache[n] = fibo(n - 2) + fibo(n - 1);
    }
  }
  return cache[n];
};

Working with objects

 

Getting a property from an object

const cities = [
  { name: 'New York', long: 40.7128, lat: 74.006 },
  { name: 'Tokyo', long: 25.2048, lat: 55.2708 },
  { name: 'Krakow', long: 50.0647, lat: 19.945 },
];

const avgLong = average(cities.map((city) => city.long));
const avgLat = average(cities.map((city) => city.lat));

Get field value

const example = {
  name: 'Tom',
  age: 26,
}

const getField = attr => obj => obj[attr];

const getName = getField('name)';
const getAge = getField('age)';

getName(example) // "Tom"
getAge(example) // 26

// From previous example
cont avgLon = average(cities.map(getField('lon'))); // 38.66076666666667
cont avgLat = average(cities.map(getField('lat')));

// Also see lodash: .get, .property, .propertyOf

Logically negating a function

const not = fn => (...args) => !fn(...args);

Reversed filter

const filterNot = arr => fn => arr.filter(not(fn));

Inverting results

const invert = fn => (...args) => -fn(...args);

Functional programming

Currying

 

const exampleFn = (a, b, c) => `${100 * a + 10 * b + c}`;
const exampleCurried = a => b => c => `${100 * a + 10 * b + c}`;

Sum numbers using currying

 

// Normal way
const sumNumbers = (a, b, c, d) => a + b + c + d;
// sumNumbers(1,2,3,4) => 10

// Currying by hand

const curriedSumNumbers = a => b => c => d => a + b + c + d;
// curriedSumNumbers(1)(2)(3)(4) => 10

Adding vat curried way

 

const addVAT = (rate, amount) => amount * (1 + rate / 100); 
// addVAT(20,500) => 600

// Curried example
const addVATcurried = rate => amount => amount * (1 + rate / 100);
const addFoodVAT = addVATcurried(18);
// addFoodVAT(100) => 118

Partial application

 

Sum numbers using partial application
// Partial application by hand
const sumNumbers = (a, b) => a + b;
const partial = (fn, ...args) => (...moreArgs) => fn(...args, ...moreArgs)
const add1 = partial(sumNumbers, 1);
// add1(2) => 3

// Using js bind
const sumNumbers = (a, b, c, d) => a + b + c + d;
const partiallyAppliedSumNumbers = sumNumbers.bind(null, 1, 2);

// partiallyAppliedSumNumbers(3,4) 10

const otherPartiallyAppliedSumNumbers = partiallyAppliedSumNumbers.bind(null, 3);
// otherPartiallyAppliedSumNumbers(4) => 10

Recursion

Decrease and conquer - searching

Checking if the value is in array

 


const isInArray = (arr, key) => {
  if (arr.length === 0) {
  	return false;
  } else if (arr[0] === key) {
  	return true;
  } else {
  	return isInArray(arr.slice(1), key);
  }
}

const numberArr = [1, 3, 4];

// isInArray(numberArr, 3) => true
// isInArray(numberArr, 3) => false

const isInArray2 = (arr, key) => arr.length === 0 ? false : arr[0] === key || isInArray2(arr.slice(1), key);

const arra = [1, 3, 4];

// isInArray(arra, 3) => true
// isInArray(arra, 2) => false

const isInArray3 = (arr, key) => arr.length && (arr[0] === key || isInArray2(arr.slice(1), key))
// this will return 0 (array length) if there's no searched value

Exponentiation of numbers

 

const powerN = (base, power) => {
	if(power === 0) {
  	return 1;
  } else if (power % 2) {
  	return base * powerN(base, power-1);
  } else {
  	return powerN(base * base, power / 2);
  }
}

// powerN(2, 10) => 1024

About

Some helpful tips, tricks, good practices and ready-made solutions in Javascript / Typescript

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published