手写数组常见方法
// 数组map
Array.prototype.myMap = function (callback) {
const arr = []
for (let i = 0; i < this.length; i++) {
arr[i] = callback(this[i], i);
}
return arr;
}
// 数组filter
Array.prototype.myFilter = function (callback) {
const arr = [];
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i)) {
arr.push(this[i]);
}
}
return arr;
}
// 数组find
Array.prototype.myFind = function (callback) {
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i)) {
return this[i];
}
}
}
//数组flat
Array.prototype.myFlat = function (depth = 1) {
return this.reduce((pre, cur) => {
return pre.concat(Array.isArray(cur) && depth > 1 ? cur.myFlat(depth - 1) : cur)
}, [])
}
// 多维数组 flatDeep
Array.prototype.myFlatDeep = function (depth = 1) {
return this.flat().reduce((pre, cur) => {
return pre.concat(Array.isArray(cur) && depth > 1 ? cur.myFlat(depth - 1) : cur)
}, [])
}
// 数组indexOf
Array.prototype.myIndexOf = function (item) {
for (let i = 0; i < this.length; i++) {
if (arr[i] === item) return i;
}
return -1;
}
// 数组 reduce
Array.prototype.myReduce = function (callback, initialValue) {
const fakeArray = [...this]
if (initialValue) {
fakeArray.unshift(initialValue);
}
let preValue = fakeArray[0];
for (let i = 0; i < fakeArray.length - 1; i++) {
preValue = callback(preValue, fakeArray[i + 1]);
}
return preValue;
}
// 反转
Array.prototype.myReverse = function () {
for (let i = 0; i < Math.floor(this.length / 2); i++) {
this[i] = this.splice(this.length - 1 - i, 1, this[i])[0];
}
return this;
}
数组的交集、并集、差集、补集
// 交集
Array.prototype.intersect = function (arr) {
return this.filter(item => arr.includes(item));
}
// 差集
Array.prototype.minus = function (arr) {
return this.filter(item => !arr.includes(item));
}
// 补集
Array.prototype.complement = function (arr) {
return [...this.filter(item => !arr.includes(item)), ...arr.filter(item => !this.includes(item))]
}
// 并集
Array.prototype.unionset = function (arr) {
return this.concat(arr.filter(v => !this.includes(v)))
}
数组元素交换、元素上移/下移、元素置顶/置底
// 交换
Array.prototype.swap = function (i, j) {
this[i] = this.splice(j, 1, this[i])[0];
return this;
}
// 上移
Array.prototype.movePrev = function (index) {
this.swap(index, index - 1);
return this;
}
// 下移
Array.prototype.moveNext = function (index) {
this.swap(index, index + 1);
return this;
}
// 置顶
Array.prototype.moveTop = function (index) {
while (index > 0) {
this.movePrev(index--);
}
return this;
}
// 置底
Array.prototype.moveBottom = function (index) {
while (index < this.length - 1) {
this.moveNext(index++);
}
return this;
}
数组批量删除(批量删除指定索引的数组元素)、去重(支持多维数组)、随机(随机抽取N个不重复元素)、乱序(数组随机打乱)
// 批量删除
Array.prototype.myBatchRemove(indexList) {
return this.filter((_, index) => indexList.indexOf(index) === -1);
}
// 数组去重(支持多维数组)
Array.prototype.myUnique = function () {
return [...new Set(this.reduce(
(pre, cur) => {
return Array.isArray(cur) ? pre.concat(...cur.myUnique()) : pre.concat(cur);
}, [])
)]
}
// 从数组中随机抽取N个不重复的元素
Array.prototype.myRandomN = function (N) {
const set = new Set()
while (set.size < N) {
const index = Math.floor(Math.random() * this.length)
set.add(this[index]);
}
return [...set];
}
// 数组乱序
Array.prototype.myDisSort = function () {
const len = this.length;
const map = {};
const ans = [];
while (ans.length < len) {
const key = Math.floor(Math.random() * len);
if (!map[key]) {
map[key] = true;
ans.push(this[key]);
}
}
return ans;
}
数组最小值、最大值、累加、
// 数组最大值
Array.prototype.myMax = function () {
return this.reduce((acc, item) => acc > item ? acc : item)
}
// 数组最小值
Array.prototype.myMin = function () {
return this.reduce((acc, item) => acc > item ? item : acc);
}
// 数组累加
Array.prototype.mySum = function () {
return this.reduce((acc, item) => acc + item);
}
数组排序
// 快排,时间复杂度(nlogn ~ n^2)
Array.prototype.myQuickSort = function () {
if (this.length === 0 || this.length === 1) return this;
const tmp = this.shift();
const left = [];
const right = [];
for (const item of this) {
if (item < tmp) {
right.push(item);
} else {
left.push(item);
}
}
return left.myQuickSort().concat(tmp, right.myQuickSort());
}
//插入排序
Array.prototype.myInsertSort = function () {
let temp;
for (let i = 1; i < this.length; i++) {
temp = this[i];
let j = i - 1;
while (j >= 0 && temp < this[j]) {
this[j + 1] = this[j];
j--;
}
this[j + 1] = temp;
}
return this;
}
数组转对象(二维数组,每一项都是一个仅有2项的字符串数组)
const array2Object = (arr) => {
return arr.reduce((pre, item) => {
pre[item[0]] = item[1];
return pre;
}, {});
}
// 测试
const arr = [
['name', 'jack'],
['age', '11'],
['sex', '男']
]
console.log(array2Object(arr));
数组转树(每一项带父级id:pid)
const arrayToTree = (arr,treeArr,pid)=>{
for(let node of arr){
if(node.pid === pid){
const newNode = {...node,children:[]};
treeArr.push(newNode);
arrayToTree(arr,newNode.children,node.id)
}
}
}
实现扑克牌排序、洗牌
function Poker () {
this.Cards = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
this.Types = ['♥️', '♠️', '♣️', '♦️']
this.Kings = ['小王', '大王']
this.Size = 54;
this.getPokerList = function () {
const ans = [];
this.Cards.forEach(item => ans.push(...this.Types.map(ele => item + ele)))
return ans.concat(this.Kings);
}
this.getRandomList = function () {
const set = new Set();
while (set.size < this.Size) {
set.add(Math.floor(Math.random() * this.Size));
}
return [...set];
}
this.refresh = function () {
const randomList = this.getRandomList();
const pokerList = this.getPokerList();
return randomList.map(item => pokerList[item]);
}
this.sort = function () {
return this.getPokerList()
}
}
// 测试
const poker = new Poker();
console.log(poker.refresh())
console.log(poker.sort());
判断给定的几个数字是否相等,如[1,1,1,1]相等
const isEqualAll = (arr) => new Set(arr).size === 1;
写一个方法检测指定的数组是否有重复的元素
const isRepeat = arr => new Set(arr).size !== arr.length;
使用js生成1-10000的数组
const array = Array.from({length: 10000}, (_, i) => i + 1);
写一个方法判断数组内元素是否全部相同
const isEqualAll = (arr) => arr.every(item => item === arr[0]);
写一个方法把多维数组降维
const getFlatArr = arr.flat(Infinity);
写一个方法判断在一个一维数组里,有且只有一个数等于给定的值
const findOnlyNum = (arr, v) => arr.filter(item => item === v).length === 1;
写一个函数找出给定数组中的最大差值
const findMaxDecrease = arr => Math.max(...arr) - Math.min(...arr);
数组元素全倒排列并去重
const removeRepeatAndSort = function (arr) {
return arr.sort((a, b) => b - a).reduce((pre, cur) => {
const len = pre.length;
if (len === 0) return [cur];
if (pre[len - 1] === cur) return pre
return pre.concat(cur);
}, [])
}
从一个无序的整数数组中,找出最小和最大数之间缺失的数字,要求最小的时间复杂度
const findMissNumber = function (arr) {
const min = Math.min(...arr);
const max = Math.max(...arr);
const ans = new Array(max - min + 1).fill(0).map((_, index) => index + min);
arr.forEach(item => ans[item] = true);
return ans.filter(item => item !== true);
}
写一个方法将一个数组中的元素,从前到后依次两两组合,最后一个与第一个组合
const buildPairs = function (arr) {
if (arr.length % 2 !== 0) return false;
const mid = arr.length / 2;
const pairs = [];
for (let i = 0; i < mid; i++) {
pairs.push([arr[i], arr[arr.length - i - 1]])
}
return pairs;
}
写一个方法,传入数字x,从一个一维数组里找到两个数字符合“n1 + n2 = x”
const get2Num = (arr, x) => {
for (let i = 0; i < arr.length; i++) {
const index = arr.indexOf(x - arr[i])
if (index !== i && index > -1) {
return [arr[i], arr[index]];
}
}
return false;
}
写一个方法找出指定一维数组所有不重复的元素和个数
const findOnly = (arr) =>arr.filter(item => arr.indexOf(item) === arr.lastIndexOf(item));
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
function sum3 (arr) {
arr = arr.sort((a, b) => a - b);
let target = 0;
const ans = [];
for (let i = 0; i < arr.length; i++) {
let left = i + 1, right = arr.length - 1;
if (i > 0 && arr[i] === arr[i - 1]) continue;
while (left < right) {
let sum = arr[i] + arr[left] + arr[right]
if (target === sum) {
ans.push([arr[i], arr[left], arr[right]]);
while (arr[left] === arr[left + 1]) left++;
while (arr[right] === arr[right - 1]) right--;
left++;
right--;
} else if (target > sum) {
left++;
} else {
right--;
}
}
}
return ans;
}
写一个方法判断一组数字是连值,比如[1,2,3],[9,0,1],这样的连值组合?连值是指12345678901234567890这样的数字相连的组合,像[1,2,3,4,5]是连值,但[1,3,4,5,6]不是,因为没有相连。
const isContinuousArr = (arr)=>arr.every((item, index) => index === 0 || item === (arr[index - 1] + 1) % 10);