JS代码片段(Math、Date)

2019-07-17  本文已影响0人  oWSQo

Math

average

返回两个或两个以上数字的的平均值。
使用Array.reduce()将每个值累加到初始值0的累加器, 除以数组长度length

const average = (...nums) => nums.reduce((acc, val) => acc + val, 0) / nums.length;

average(...[1, 2, 3]); // 2
average(1, 2, 3); // 2

averageBy

使用提供的函数将每个元素映射到一个值后,返回一个数组的平均值。
使用Array.map()将每个元素映射到由fn返回的值,Array.reduce()将每个值累加到累加器,用0作为累加器的初始值,再除以数组的length

const averageBy = (arr, fn) =>
  arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val) => acc + val, 0) /
  arr.length;

averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n); // 5
averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 5

clampNumber

返回由边界值ab限定范围内的num
如果num在限定范围内,则返回num。 否则,返回范围内最接近的数字。

const clampNumber = (num, a, b) => Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b));

clampNumber(2, 3, 5); // 3
clampNumber(1, -1, -5); // -1

digitize

将数字转换为数字数组。
将数字转换为字符串,使用展开运算符 (...) 构建一个数组。 使用Array.map()parseInt()将每个值转换为整数。

const digitize = n => [...`${n}`].map(i => parseInt(i));

digitize(123); // [1, 2, 3]

distance

返回两点之间的欧氏距离。
使用Math.hypot()计算两点之间的欧氏距离( Euclidean distance)。

const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0);

distance(1, 1, 2, 3); // 2.23606797749979

factorial

计算一个数字的阶乘。
使用递归。如果n小于或等于1 ,则返回1 。否则返回nn - 1的阶乘。如果n是负数,则会引发异常。

const factorial = n =>
  n < 0
    ? (() => {
      throw new TypeError('Negative numbers are not allowed!');
    })()
    : n <= 1
      ? 1
      : n * factorial(n - 1);

factorial(6); // 720

fibonacci

生成一个包含 斐波纳契(fibonacci)数组,直到该数组有第n元素。
创建一个指定长度的空数组,初始化前两个值( 0和1 )。使用Array.reduce()向数组中添加值,该值是最后两个值的和,前两个值除外。

const fibonacci = n =>
  Array.from({ length: n }).reduce(
    (acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),
    []
  );

fibonacci(6); // [0, 1, 1, 2, 3, 5]

gcd

计算两个或两个以上数字/数字数组的最大公约数。
内部的_gcd函数使用递归。基本情况是,当y等于0的情况下,返回x。否则,返回y的最大公约数和x / y的其余数。

const gcd = (...arr) => {
  const _gcd = (x, y) => (!y ? x : gcd(y, x % y));
  return [...arr].reduce((a, b) => _gcd(a, b));
};

gcd(8, 36); // 4
gcd(...[12, 8, 32]); // 4

geometricProgression

初始化一个包含指定范围中数字的数组,包含startend,两个元素之间的比例是step(后一个数是前一个数的step倍)。 如果step等于1则返回一个错误。
使用Array.from()Math.log()Math.floor()来创建一个所需长度的数组,使用Array.map()来填充所需的值。省略第二个参数start,使用默认值1。省略第三个参数step,使用默认值2。

const geometricProgression = (end, start = 1, step = 2) =>
  Array.from({ length: Math.floor(Math.log(end / start) / Math.log(step)) + 1 }).map(
    (v, i) => start * step ** i
  );

geometricProgression(256); // [1, 2, 4, 8, 16, 32, 64, 128, 256]
geometricProgression(256, 3); // [3, 6, 12, 24, 48, 96, 192]
geometricProgression(256, 1, 4); // [1, 4, 16, 64, 256]

inRange

检查给定的数字是否在给定范围内。
使用算术比较来检查给定的数字是否在指定的范围内。如果没有指定第三个参数end,则范围被认为是从0到start

const inRange = (n, start, end = null) => {
  if (end && start > end) [end, start] = [start, end];
  return end == null ? n >= 0 && n < start : n >= start && n < end;
};

inRange(3, 2, 5); // true
inRange(3, 4); // true
inRange(2, 3, 5); // false
inRange(3, 2); // false

isDivisible

检查第一个数字参数是否可被第二个数字整除。
使用模运算符(%)来检查余数是否等于0 。

const isDivisible = (dividend, divisor) => dividend % divisor === 0;

isDivisible(6, 3); // true

isEven

如果给定的数字是偶数,则返回true,否则返回false
使用模运算符(%)来检查数字是奇数还是偶数。如果数字是偶数,则返回true,如果是奇数,则返回false

const isEven = num => num % 2 === 0;

isEven(3); // false

isPrime

检查提供的整数是否为素数。
检查数字从2到给定数字的平方根。如果它们中的任何一个可以整除给定的数字,则返回false,否则返回true,除非数字小于2。

const isPrime = num => {
  const boundary = Math.floor(Math.sqrt(num));
  for (var i = 2; i <= boundary; i++) if (num % i === 0) return false;
  return num >= 2;
};

isPrime(11); // true

lcm

返回两个或两个以上数字的最小公倍数。
使用最大公约数(GCD)公式和lcm(x,y) = x * y / gcd(x,y)来确定最小公倍数。 GCD公式使用递归。

const lcm = (...arr) => {
  const gcd = (x, y) => (!y ? x : gcd(y, x % y));
  const _lcm = (x, y) => (x * y) / gcd(x, y);
  return [...arr].reduce((a, b) => _lcm(a, b));
};

lcm(12, 7); // 84
lcm(...[1, 3, 4, 5]); // 60

maxBy

使用提供的函数将每个元素映射到一个值后,然后返回数组的最大值。
使用Array.map()将每个元素映射到由fn,然后用Math.max()返回的值来获取最大值。

const maxBy = (arr, fn) => Math.max(...arr.map(typeof fn === 'function' ? fn : val => val[fn]));

maxBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n); // 8
maxBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 8

median

返回数字数组的中值。
找到数字数组的中间值,使用 Array.sort()对值进行排序。 如果length是奇数,则返回中间值数字,否则返回两个中间值数值的平均值。

const median = arr => {
  const mid = Math.floor(arr.length / 2),
    nums = [...arr].sort((a, b) => a - b);
  return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2;
};

median([5, 6, 50, 1, -5]); // 5

minBy

使用提供的函数将每个元素映射到一个值后,然后返回数组的最小值。
使用Array.map()将每个元素映射到由fn,然后用Math.min()返回的值来获取最小值。

const minBy = (arr, fn) => Math.min(...arr.map(typeof fn === 'function' ? fn : val => val[fn]));

minBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n); // 2
minBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 2

percentile

使用百分比表示给定数组中有多少个数字小于或等于给定值。
使用Array.reduce()来计算有多少个数字小于等于该值,并用百分比表示。

const percentile = (arr, val) =>
  (100 * arr.reduce((acc, v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0)) / arr.length;

percentile([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 6); // 55

powerset

返回给定数组的powerset(幂集)。
使用Array.reduce()Array.map()结合来遍历元素,并将其组合成一个包含所有排列组合的数组。

const powerset = arr => arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]);

powerset([1, 2]); // [[], [1], [2], [2, 1]]

randomIntArrayInRange

返回指定范围内n个随机整数的数组。
使用array.from()创建一个特定长度的空数组math.random(),生成一个随机数并将其映射到所需的范围,使用math.floor()将其设置为整数。

const randomIntArrayInRange = (min, max, n = 1) =>
  Array.from({ length: n }, () => Math.floor(Math.random() * (max - min + 1)) + min);

randomIntArrayInRange(12, 35, 10); // [ 34, 14, 27, 17, 30, 27, 20, 26, 21, 14 ]

randomIntegerInRange

返回指定范围内的随机整数。
使用Math.random()生成一个随机数并将其映射到所需的范围,使用Math.floor()使其成为一个整数。

const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;

randomIntegerInRange(0, 5); // 2

randomNumberInRange

返回指定范围内的一个随机数。
使用Math.random()生成一个随机值,使用乘法将其映射到所需的范围。

const randomNumberInRange = (min, max) => Math.random() * (max - min) + min;

randomNumberInRange(2, 10); // 6.0211363285087005

round

将数字四舍五入到指定的小数位数。
使用Math.round()和模板字面量将数字四舍五入为指定的小数位数。 省略第二个参数decimals,数字将被四舍五入到一个整数。

const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`);

round(1.005, 2); // 1.01

sum

返回两个或两个以上数字/数字数组中元素之和。
使用Array.reduce()将每个值添加到累加器,并且累加器初始值为0。

const sum = (...arr) => [...arr].reduce((acc, val) => acc + val, 0);

sum(1, 2, 3, 4); // 10
sum(...[1, 2, 3, 4]); // 10

sumBy

使用提供的函数将每个元素映射到一个值之后,然后返回数组的和。
使用Array.map()将每个元素映射到由fn返回的值,Array.reduce()将每个值添加到一个累加器,并且累加器初始值为0。

const sumBy = (arr, fn) =>
  arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val) => acc + val, 0);

sumBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n); // 20
sumBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 20

toSafeInteger

将值转换为安全整数。
使用Math.max()Math.min()来找到最接近的安全值。 使用Math.round()转换为一个整数。

const toSafeInteger = num =>
  Math.round(Math.max(Math.min(num, Number.MAX_SAFE_INTEGER), Number.MIN_SAFE_INTEGER));

toSafeInteger('3.2'); // 3
toSafeInteger(Infinity); // 9007199254740991

Date

formatDuration

返回给定毫秒数的可读格式。
用适当的值来划分ms,以获得day,hour,minute,secondmillisecond的适当值。通过Array.filter()使用Object.entries()只保留非零值。使用Array.map()为每个值创建字符串,并且适当复数化。使用String.join(', ')将这些值组合成一个字符串。

const formatDuration = ms => {
  if (ms < 0) ms = -ms;
  const time = {
    day: Math.floor(ms / 86400000),
    hour: Math.floor(ms / 3600000) % 24,
    minute: Math.floor(ms / 60000) % 60,
    second: Math.floor(ms / 1000) % 60,
    millisecond: Math.floor(ms) % 1000
  };
  return Object.entries(time)
    .filter(val => val[1] !== 0)
    .map(([key, val]) => `${val} ${key}${val !== 1 ? 's' : ''}`)
    .join(', ');
};

formatDuration(1001); // '1 second, 1 millisecond'
formatDuration(34325055574); 
// '397 days, 6 hours, 44 minutes, 15 seconds, 574 milliseconds'

getColonTimeFromDate

从日期对象返回格式为hh:mm:ss的字符串。
使用date.prototype.toTimeString()string.prototype.slice()获取给定日期对象的hh:mm:ss部分。

const getColonTimeFromDate = date => date.toTimeString().slice(0, 8);

getColonTimeFromDate(new Date()); // "08:38:00"

getDaysDiffBetweenDates

返回两个日期之间相差的天数。
计算Date对象之间的差异(以天为单位)。

const getDaysDiffBetweenDates = (dateInitial, dateFinal) =>
  (dateFinal - dateInitial) / (1000 * 3600 * 24);

getDaysDiffBetweenDates(new Date('2017-12-13'), new Date('2017-12-22')); // 9

tomorrow

以字符串形式返回明天日期表示。
使用new Date()获取今天的日期,加上86400000秒(24小时),使用Date.toISOString()Date对象转换为字符串。

const tomorrow = () => {
  let t = new Date();
  t.setDate(t.getDate() + 1);
  return t.toISOString().split('T')[0];
};

tomorrow(); // 2018-10-19 (if current date is 2018-10-18)
上一篇下一篇

猜你喜欢

热点阅读