numberToChinese

  1. const fraction = ['角', '分']
  2. const defaultDigit = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
  3. // 遍历unit[1] 进位 unit[0]
  4. const unit = [
  5. ['元', '万', '亿'],
  6. ['', '拾', '佰', '仟'],
  7. ]
  8. // 阿拉伯数值转换 大写 数值
  9. interface IUppercaseConfig {
  10. /***
  11. * @description default is '整'
  12. * */
  13. tail?: string
  14. /***
  15. * @description default is ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
  16. * */
  17. digit?: string[]
  18. }
  19. export function numberToChinese(n: number | string, config?: IUppercaseConfig): string {
  20. const { digit = defaultDigit, tail = '整' } = config ?? {}
  21. try {
  22. // 超出最大解析限制
  23. if (String(n).length > 13) {
  24. return ''
  25. }
  26. const head = n < 0 ? '负' : ''
  27. n = Math.abs(n as number)
  28. let s = ''
  29. // 小数位转换
  30. for (let i = 0; i < fraction.length; i++) {
  31. s += (digit[Math.floor(n * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(/零./, '')
  32. }
  33. s = s || tail
  34. n = Math.floor(n)
  35. for (let i = 0; i < unit[0].length && n > 0; i++) {
  36. let p = ''
  37. for (let j = 0; j < unit[1].length && n > 0; j++) {
  38. p = digit[n % 10] + unit[1][j] + p
  39. n = Math.floor(n / 10)
  40. }
  41. s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s
  42. }
  43. return (
  44. head +
  45. s
  46. .replace(/(零.)*零元/, '元')
  47. .replace(/(零.)+/g, '零')
  48. .replace(/^整$/, '零元整')
  49. )
  50. } catch (e) {
  51. return ''
  52. }
  53. }

对象深度比较

对象属性顺序可以不一致,只要属性类型及其值相同,则判定为该属性相同

  1. function deepCompare(x, y) {
  2. var i, l, leftChain, rightChain;
  3. function compare2Objects(x, y) {
  4. var p;
  5. // remember that NaN === NaN returns false
  6. // and isNaN(undefined) returns true
  7. if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') {
  8. return true;
  9. }
  10. // Compare primitives and functions.
  11. // Check if both arguments link to the same object.
  12. // Especially useful on the step where we compare prototypes
  13. if (x === y) {
  14. return true;
  15. }
  16. // Works in case when functions are created in constructor.
  17. // Comparing dates is a common scenario. Another built-ins?
  18. // We can even handle functions passed across iframes
  19. if ((typeof x === 'function' && typeof y === 'function') ||
  20. (x instanceof Date && y instanceof Date) ||
  21. (x instanceof RegExp && y instanceof RegExp) ||
  22. (x instanceof String && y instanceof String) ||
  23. (x instanceof Number && y instanceof Number)) {
  24. return x.toString() === y.toString();
  25. }
  26. // At last checking prototypes as good as we can
  27. if (!(x instanceof Object && y instanceof Object)) {
  28. return false;
  29. }
  30. if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) {
  31. return false;
  32. }
  33. if (x.constructor !== y.constructor) {
  34. return false;
  35. }
  36. if (x.prototype !== y.prototype) {
  37. return false;
  38. }
  39. // Check for infinitive linking loops
  40. if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) {
  41. return false;
  42. }
  43. // Quick checking of one object being a subset of another.
  44. // todo: cache the structure of arguments[0] for performance
  45. for (p in y) {
  46. if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
  47. return false;
  48. } else if (typeof y[p] !== typeof x[p]) {
  49. return false;
  50. }
  51. }
  52. for (p in x) {
  53. if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
  54. return false;
  55. } else if (typeof y[p] !== typeof x[p]) {
  56. return false;
  57. }
  58. switch (typeof(x[p])) {
  59. case 'object':
  60. case 'function':
  61. leftChain.push(x);
  62. rightChain.push(y);
  63. if (!compare2Objects(x[p], y[p])) {
  64. return false;
  65. }
  66. leftChain.pop();
  67. rightChain.pop();
  68. break;
  69. default:
  70. if (x[p] !== y[p]) {
  71. return false;
  72. }
  73. break;
  74. }
  75. }
  76. return true;
  77. }
  78. if (arguments.length < 1) {
  79. return true; //Die silently? Don't know how to handle such case, please help...
  80. // throw "Need two or more arguments to compare";
  81. }
  82. for (i = 1, l = arguments.length; i < l; i++) {
  83. leftChain = []; //Todo: this can be cached
  84. rightChain = [];
  85. if (!compare2Objects(arguments[0], arguments[i])) {
  86. return false;
  87. }
  88. }
  89. return true;
  90. }

扁平数据结构转tree

  1. function arrayToTree(items) {
  2. const result = []; // 存放结果集
  3. const itemMap = {}; //
  4. for (const item of items) {
  5. const id = item.id;
  6. const pid = item.pid;
  7. if (!itemMap[id]) {
  8. itemMap[id] = {
  9. children: [],
  10. }
  11. }
  12. itemMap[id] = {
  13. ...item,
  14. children: itemMap[id]['children']
  15. }
  16. const treeItem = itemMap[id];
  17. if (pid === 0) {
  18. result.push(treeItem);
  19. } else {
  20. if (!itemMap[pid]) {
  21. itemMap[pid] = {
  22. children: [],
  23. }
  24. }
  25. itemMap[pid].children.push(treeItem)
  26. }
  27. }
  28. return result;
  29. }

快排

  1. const arr = [19, 9, 8, 7, 6, 5, 4, 3, 2, 1, -2];
  2. function quickSort(arr, low, high) {
  3. if (low < high) {
  4. const index = getIndex(arr, low, high);
  5. quickSort(arr, low, index - 1);
  6. quickSort(arr, index + 1, high);
  7. }
  8. }
  9. function getIndex(arr, low, high) {
  10. const temp = arr[low];
  11. while (low < high) {
  12. while (low < high && arr[high] >= temp) high--;
  13. arr[low] = arr[high];
  14. while (low < high && arr[low] <= temp) low++;
  15. arr[high] = arr[low];
  16. }
  17. arr[low] = temp;
  18. return low;
  19. }
  20. quickSort(arr, 0, arr.length - 1);
  21. console.log(arr);