{"id":21985015,"url":"https://github.com/minsion/js-algorithm","last_synced_at":"2025-04-30T07:50:35.184Z","repository":{"id":230702944,"uuid":"779983683","full_name":"minsion/js-algorithm","owner":"minsion","description":"持续更新常用JavaScript算法（continuously update common JavaScript algorithms）","archived":false,"fork":false,"pushed_at":"2024-07-22T11:11:39.000Z","size":69997,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-07-22T13:23:37.605Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/minsion.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-31T11:09:14.000Z","updated_at":"2024-07-22T11:11:42.000Z","dependencies_parsed_at":"2024-03-31T11:28:02.003Z","dependency_job_id":"fa994f46-9a84-4ecf-9c73-159ec27d613b","html_url":"https://github.com/minsion/js-algorithm","commit_stats":null,"previous_names":["minsion/js-algorithm"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minsion%2Fjs-algorithm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minsion%2Fjs-algorithm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minsion%2Fjs-algorithm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minsion%2Fjs-algorithm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/minsion","download_url":"https://codeload.github.com/minsion/js-algorithm/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227185457,"owners_count":17744371,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-29T18:12:16.936Z","updated_at":"2024-11-29T18:12:17.624Z","avatar_url":"https://github.com/minsion.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## js-algorithm\n持续更新常见JavaScript算法\n\n### 1.定义一个函数，将 12378900 转换为 12,378,900\n\n```js\n# 12300 transform 12,300\n\nfunction thousandSeparator(number) {\n  let result = [];\n  let rest = String(Math.abs(number));\n  while (rest.length) {\n    result.push(rest.slice(-3));\n    rest = rest.slice(0, -3);\n  }\n  const r = result.reverse().join(\",\");\n  return number \u003c 0 ? \"-\" + r : r\n}\nconsole.log(666, thousandSeparator(12300))\n```\n\n### 2.myReduce\n```js\nArray.prototype.myReduce = function (callback, initialValue) {\n  let arr = this;\n  let pre = initialValue ? initialValue : arr[0];\n  let i = initialValue ? 0 : 1;\n  for (i; i \u003c arr.length; i++) {\n    pre = callback(pre, arr[i]);\n  }\n  return pre;\n}\nconst res = [1, 2, 3, 4].myReduce((pre, cur) =\u003e {\n  return pre + cur;\n}, 1);\nconsole.log('myReduce', res);\n```\n### 3.inherit\n```js\nvar Person = function (name, age) {\n  this.name = name;\n  this.age = age;\n}\nPerson.prototype.test = \"this is a test\";\nPerson.prototype.testFunc = function () {\n  console.log('this is a testFunc');\n}\n\n// 子类\nvar Student = function (name, age, gender, score) {\n  Person.apply(this, [name, age]); // 盗用构造函数\n  this.gender = gender;\n  this.score = score;\n}\n// 1. 改变 Student 构造函数的原型对象\n// Student.prototype = new Person(); \n// 2.圣杯模式\nStudent.prototype = Object.create(Person.prototype);\nStudent.prototype.constructor = Student;\n\nStudent.prototype.testStuFunc = function () {\n  console.log('this is a testStuFunc');\n}\n\n// 测试\nvar zhangsan = new Student(\"张三\", 18, \"男\", 100);\nconsole.log(zhangsan.name); // 张三\nconsole.log(zhangsan.age); // 18\nconsole.log(zhangsan.gender); // 男\nconsole.log(zhangsan.score); // 100\nconsole.log(zhangsan.test); // this is a test\nzhangsan.testFunc(); // this is a testFunc\nzhangsan.testStuFunc(); // this is a testStuFunc\nconsole.log(Student.prototype)\n```\n### 4. call, apply, bind\n```js\nfunction P(age, country) {\n  console.log(`Hello, my name is ${this.name} and I am ${age}, I am from ${country}`);\n}\n/*\n\n1. call 函数允许你在特定上下文中调用函数\nfunction.call(context, arg1, arg2, ...)\n\n2. apply 函数与 call 函数类似，也允许你在特定上下文中调用函数。不同之处在于 apply 函数需要以数组形式传递参数\nfunction.apply(context, [argsArray])\n\n1. bind 函数与 call 和 apply 函数不同。它不会立即调用函数。而是返回一个将绑定到指定上下文的新函数，\n当调用该函数时，它将以指定的上下文运行。\nfunction.bind(thisArg, arg1, arg2, ...)\n*/\nP.call({name: 'mary'}, '12', 'USA')\nP.apply({name: 'lilei'}, ['13', 'France'])\nP.bind({name: 'tom'}, '11', 'China')\n\n// 5. 自定义call、apply、bind\n// 实现call方法\nFunction.prototype.myCall = function (context, ...args) {\n  // 如果context参数为空，则默认为window对象\n  context = context || window;\n  // 使用Symbol函数创建唯一标识符\n  const fnSymbol = Symbol();\n  // 将原始函数存储为context对象的属性\n  context[fnSymbol] = this;\n  // 调用函数并将结果存储在 result 变量中\n  const result = context[fnSymbol](...args);\n  // 删除 context 对象的属性\n  delete context[fnSymbol];\n  // 返回函数的结果\n  return result;\n};\n\n// 实现 apply 方法\nFunction.prototype.myApply = function (context, args) {\n  // 如果 context 参数为空，则默认为 window 对象\n  context = context || window;\n  // 使用 Symbol 函数创建唯一标识符\n  const fnSymbol = Symbol();\n  // 将原始函数存储为 context 对象的属性\n  context[fnSymbol] = this;\n  // 调用函数并将结果存储在 result 变量中\n  const result = context[fnSymbol](...args);\n  // 删除 context 对象的属性\n  delete context[fnSymbol];\n  // 返回函数的结果\n  return result;\n};\n\n// 实现 bind 方法\nFunction.prototype.myBind = function (context, ...args) {\n  // 将 this 绑定到 fn 变量中\n  const fn = this;\n  // 返回一个新函数，该函数将传递的参数与新函数的参数合并，并在新上下文中使用 apply 调用原始函数\n  return function (...newArgs) {\n  return fn.apply(context, [...args, ...newArgs]);\n  };\n};\nP.myCall({name: 'mary'}, '12', 'USA')\nP.myApply({name: 'lilei'}, ['13', 'France'])\nP.myBind({name: 'tom'}, '11', 'China')\n```\n\n### 5.检查是否是类的对象实例\n```js\nconst checkIfInstanceOf = (obj, classFunction) =\u003e {\n  if (classFunction === null) return false;\n  while (obj !== null) {\n    if (obj.__proto__ === classFunction.prototype) {\n      return true\n    };\n    obj = obj.__proto__;\n  }\n  return false;\n}\nclass Animal {};\nclass Dog extends Animal {};\n\nconsole.log('checkIfInstanceOf', checkIfInstanceOf(new Date(), Date)) // true\nconsole.log('checkIfInstanceOf', checkIfInstanceOf(new Dog(), Animal)) // true\nconsole.log('checkIfInstanceOf', checkIfInstanceOf(Date, Date)) // false\nconsole.log('checkIfInstanceOf', checkIfInstanceOf(5, Number)) // true\nconsole.log('checkIfInstanceOf', checkIfInstanceOf([], Array)) // true\n```\n### 6.数组原型对象的最后一个元素\n```js\nArray.prototype.last = function() {\n  const len = this.length\n  return len ? this[len - 1] : -1\n}\nconsole.log([1, 2, 3].last()); // 3\nconsole.log([].last()); // -1\n```\n### 7.counter\n```js\n/**\n * @param {number} n\n * @return {Function} counter\n */\nvar createCounter = function(n) {\n  return function() {\n      return n++\n  };\n};\n\nconst counter = createCounter(10)\ncounter() // 10\ncounter() // 11\ncounter() // 12\n```\n\n### 8.休眠函数编写一个异步函数，该函数接受正整数参数 millis 并休眠 millis 毫秒。此函数需要能够解释任何值。\n```js\n/**\n * @param {number} millis\n * @return {Promise}\n */\nasync function sleep(millis) {\n  return new Promise((resolve, reject) =\u003e {\n      setTimeout(resolve, millis)\n  })\n}\n\nlet t = Date.now()\nsleep(100).then(() =\u003e console.log(Date.now() - t)) // 100\n```\n### 9.Array flat\n```js\n/**\n * @param {Array} arr\n * @param {number} depth\n * @return {Array}\n */\n\nArray.prototype.myFlat = function(deep) {\n  let arr = this;\n  let result = [];\n  if (deep === 0) {\n    return arr;\n  }\n  for (let i = 0; i \u003c arr.length; i++) {\n    if (Array.isArray(arr[i])) {\n      result.push(...arr[i].myFlat(deep - 1));\n    } else {\n      result.push(arr[i]);\n    }\n  }\n  return result;\n}\nconsole.log('myFlat', [1,2,3,[4,5,6],[7,8,[9,10,11],12],[13,14,15]].myFlat(2))\n\n```\n### 10.add and sub 方法\n```js\nNumber.prototype.add = function(n) {\n  return this + n\n}\nNumber.prototype.sub = function(n) {\n  return this - n\n}\n\nconsole.log('(5).add(3).sub(2)',(5).add(3).sub(2)) // 6\n```\n\n### 11.sum 方法\n```js\nconst myAdd = (min, max) =\u003e {\n  let sum = 0\n  for (let i = min; i \u003c= max; i++) {\n    sum = sum + i\n  }\n  return sum\n}\n\nconsole.log('myAdd', myAdd(1, 100))\n```\n### 12.交集\n```js\n// 在西雅图的公司远程工作，因为月中算法考核，半月的绩效奖金没了。。。\nconst intersect = function (nums1, nums2) {\n  let result = []\n  let longArr = nums1.length \u003e nums2.length ? nums1 : nums2;\n  let shortArr = nums1.length \u003e nums2.length ? nums2 : nums1;\n\n  for (let i = 0; i \u003c shortArr.length; i++) {\n    let longIndex = longArr.indexOf(shortArr[i])\n    if (longIndex != -1) {\n      result.push(longArr.splice(longIndex, 1)[0])\n    }\n  }\n  return result\n};\n\nintersect([1,2,1,2], [2,2,2]) // [2, 2, 2]\nintersect([4,9,5], [9,4,9,8,4]) // [4, 9]\nintersect([3,1,2], [2,2]) // [2]\n```\n### 13.数组排序\n```js\n/**\n * @param {number[]} nums\n * @return {number[]}\n */\nconst sortArray = function (nums) {\n  const { length } = nums;\n  for (let i = 0; i \u003c length; i++) {\n    for (let j = 0; j \u003c length - 1 - i; j++) {\n      if (nums[j] \u003e nums[j + 1]) {\n        [nums[j], nums[j + 1]] = [nums[j + 1], nums[j]];\n      }\n    }\n  }\n  return nums;\n};\nsortArray([1, 3, 9, 5, 2, 4, 6])\n```\n### 13.柯里化\n```js\n/* \n在这种情况下，curry 函数接受一个函数 fn 作为参数，并返回一个经过 currying 的新函数。\n在调用 curryed 函数时，它会检查传入的参数数量是否大于或等于原函数 fn 的参数数量（arity）。\n如果是，则直接调用原函数；否则，它会返回一个接受剩余参数（rest）的新函数，并将之前传入的参数（args）与剩余参数合并，然后再调用 curryed 函数。这样就实现了函数 currying。\n*/\n\nconst curry = (fn) =\u003e {\n  const arity = fn.length;\n  return function curried(...args) {\n    if (args.length \u003e= arity) {\n      return fn.apply(this, args);\n    } else {\n      return function (...rest) {\n        return curried.apply(this, args.concat(rest));\n      };\n    }\n  };\n}\nconst getURL = (protocol, domain, path) =\u003e {\n  return protocol + \"://\" + domain + \"/\" + path;\n}\nconst myurl = getURL('http', 'mysite', 'home.html');\nconst myurl2 = getURL('http', 'mysite', 'about.html');\nconsole.log('myurl', myurl);\nconsole.log('myurl2', myurl2);\n\nconst curry = (fn) =\u003e {\n  const arity = fn.length;\n  return function curried(...args) {\n    if (args.length \u003e= arity) {\n      return fn.apply(this, args);\n    } else {\n      return function (...rest) {\n        return curried.apply(this, args.concat(rest));\n      };\n    }\n  };\n}\nconst getURL = (protocol, domain, path) =\u003e {\n  return protocol + \"://\" + domain + \"/\" + path;\n}\nconst myurl = getURL('http', 'mysite', 'home.html');\nconst myurl2 = getURL('http', 'mysite', 'about.html');\nconsole.log('myurl', myurl);\nconsole.log('myurl2', myurl2);\n\n// 减少重复传递不变的参数\nconst superGetURL = curry(getURL)('https', 'mysite');\nconst myurl3 = superGetURL('detail.html')\n\nconsole.log('myurl3', myurl3);\n\n```\n\n### 13.继承\n```js\nvar Person = function (name, age) {\n  this.name = name;\n  this.age = age;\n}\nPerson.prototype.test = \"this is a test\";\nPerson.prototype.testFunc = function () {\n  console.log('this is a testFunc');\n}\n\nvar Student = function (name, age, gender, score) {\n  Person.apply(this, [name, age]);// Stealing the constructor\n  this.gender = gender;\n  this.score = score;\n}\nStudent.prototype = new Person(); // Change the prototype object of the Student constructor\nStudent.prototype.testStuFunc = function () {\n  console.log('this is a testStuFunc');\n}\n\n// 测试\nvar zhangsan = new Student(\"张三\", 18, \"男\", 100);\nconsole.log(zhangsan.name); // 张三\nconsole.log(zhangsan.age); // 18\nconsole.log(zhangsan.gender); // 男\nconsole.log(zhangsan.score); // 100\nconsole.log(zhangsan.test); // this is a test\nzhangsan.testFunc(); // this is a testFunc\nzhangsan.testStuFunc(); // this is a testStuFunc\n\n```\n\n### 14.更新...","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fminsion%2Fjs-algorithm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fminsion%2Fjs-algorithm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fminsion%2Fjs-algorithm/lists"}