导航


HTML

CSS

JavaScript

浏览器 & 网络

版本管理

框架

构建工具

TypeScript

性能优化

算法

UI、组件库

Node

业务技能

针对性攻坚

公共类

基础设施

AI


数组的常用方法有哪些?

方法 作用 是否影响原数组
push 在数组后添加元素,返回长度 ✅
unshift 数组开头添加元素,返回长度 ✅
pop 删除数组最后一项,返回被删项 ✅
shift 删除数组第一项,返回被删项 ✅
reserve 反转数组,返回数组 ✅
sort 排序数组,返回数组 ✅
splice 截取数组,返回被截取部分 ✅
join 将数组变字符串,返回字符串 ❌
concat 连接数组 ❌
map 相同规则处理数组项,返回新数组 ❌
forEach 遍历数组 ❌
filter 过滤数组项,返回符合条件的数组 ❌
every 每一项符合规则才返回true ❌
some 只要有一项符合规则就返回true ❌
reduce 接受上一个return和数组下一项 ❌
flat 数组扁平化 ❌
slice 截取数组,返回被截取区间 ❌

🔥 forEach 如何跳出循环?

function getItemById(arr, id) {
  var item = null;
  try {
    arr.forEach(function (curItem, i) {
      console.log(i)
      if (curItem.id == id) {
        item = curItem;
        throw Error();
      }
    })
  } catch (e) {}
  return item;
}

清空数组

var arr = [12, 1, 24, -123, 12123123];

arr.length = 0;
// arr.splice(0, arr.length);
// 通过将空数组 [] 赋值给数组(严格意义来说这只是将arr重新赋值为空数组,
// 之前的数组如果没有引用在指向它将等待垃圾回收。)
// arr = [];
console.log(arr);

如何实现数组的随机排序?

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// 随机交换数组内的元素 ✅
function result(arr) {
    for (let i = 0; i < arr.length; i++) {
        // 随机索引【Math.random()返回一个浮点,  伪随机数在范围[0,1)】
        let randomIndex = parseInt(Math.random() * arr.length);
        // 存下当前正常索引值对应的数字
        let curNum = arr[i];
        // 将其重新赋值为随机索引对应的数字
        arr[i] = arr[randomIndex];
        // 将随机索引对应的数字替换为当前正常索引值对应的数字
        arr[randomIndex] = curNum;
    }
    return arr;
}

// sort()可以调用一个函数做为参数,如果这个函数返回的值为负数表示数组中的a项排在b项前
var arr = [1,2,3,4,5,6,7,8,9,10];
arr.sort(() => Math.random() - 0.5)
console.log(arr);

🔥 对下面数组进行排重,并按升序排序,代码尽量简练:

const array = [ '2', 'b', '9','a','7','3','4','b','6', '4' ];
function handle(arr) {
   // ...your code
}
handle(array); // output: ['2', '3', '4', '6', '7', '9', 'a', 'b']
const array = [ '2', 'b', '9','a','7','3','4','b','6', '4' ];
function handle(arr) {
  return Array.from(new Set(arr))
          .sort((a, b) => a.charCodeAt(0) - b.charCodeAt(0));
}
console.log(handle(array)); // output: ['2', '3', '4', '6', '7', '9', 'a', 'b']

🔥 自定义 unshift

var arr = [1, 2, 3];

Array.prototype.myUnshift = function() {
  // 在数组打头,添加一个或多个元素,最后返回最新数组的长度
  var len = arguments.length;
  for (let i = len - 1; i >= 0; i--) {
    const element = arguments[i];
    this.splice(0, 0, element);
  }
  return this.length;
}

// console.log(arr.unshift(3, 2, 1), arr);
console.log(arr.myUnshift(3), arr);
var arr = [1, 2, 3];

Array.prototype.myUnshift = function() {
  var pos = 0;
  for (let i = 0; i < arguments.length; i++) {
    const element = arguments[i];
    this.splice(pos, 0, element);
    pos++;
  }
  
  return this.length;
}

// console.log(arr.unshift(3, 2, 1), arr);
console.log(arr.myUnshift(3, 2, 1), arr);

🔥 数组按照元素的总字节数长度排序

var arr = ['Are you OK', 'Lance', 'Jerry', '我爱你'];
// unicode 0-255 1个字节;256 2个字节

var getBytes = function(str) {
	// 先把每个字符都当一个字节算
  var bytes = str.length;

  for (var i = 0; i < str.length; i++) {
  	if (str.**charCodeAt**(i) > **255**) {
    	bytes++;
    }
  }

  return bytes;
}

arr.sort(function(a, b) {
	return getBytes(a) - getBytes(b);
});

// 结果: [ 'Lance', 'Jerry', '我爱你', 'Are you OK' ]

🔥 数组去重

1. 循环 通过 hasOwnProperty 判断新数组是否有该属性(问题:{} 会被解析成'[object Object]')
var arr = [
  {}, {},
  '', '',
  233, 233, '233',
  'abc',
  undefined,
  null, null,
  NaN, NaN,
  123,
  [2], [2],
  [2, 3]
];

Array.prototype.myUnique = function() {
	var hash = {},
			newArr = [];
  for (var i = 0; i < this.length; i++) {
		var item = this[i];
  	if (!hash.hasOwnProperty(typeof item + JSON.stringify(item))) {
			hash[typeof item + JSON.stringify(item)] = item;
			newArr.push(item);
    }
  }

  return newArr;
};

console.log(arr.myUnique());
// [
//   {},       '',
//   233,      '233',
//   'abc',    undefined,
//   null,     NaN,
//   123,      [ 2 ],
//   [ 2, 3 ]
// ]
2. ES6 Set
Array.prototype.myUnique = function() {
	return Array.from(new Set(this));
};

// [
//   {},        {},
//   '',        233,
//   '233',     'abc',
//   undefined, null,
//   NaN,       123,
//   [ 2 ],     [ 2 ],
//   [ 2, 3 ]
// ]
3. 利用 includes 检测数组是否有某个值  或者 indexOf 判断索引
Array.prototype.myUnique = function() {
	let arr = [];
  for (let i = 0; i < this.length; i++) {
    if (!arr.includes(this[i])) {
      arr.push(this[i]);
    }
  }
  return arr;
};

// [
//   {},        {},
//   '',        233,
//   '233',     'abc',
//   undefined, null,
//   NaN,       123,
//   [ 2 ],     [ 2 ],
//   [ 2, 3 ]
// ]
4. Map
Array.prototype.myUnique = function() {
  let map = new Map(), arr = [];
  for (let i = 0; i < this.length; i++) {
    if (!map.has(this[i])) {
      map.set(this[i], this[i]);
      arr.push(this[i]);
    }
  }
  return arr;
}

// [
//   {},        {},
//   '',        233,
//   '233',     'abc',
//   undefined, null,
//   NaN,       123,
//   [ 2 ],     [ 2 ],
//   [ 2, 3 ]
// ]
5. filter (问题:无法识别NaN)
Array.prototype.myUnique = function() {
  return this.filter((v, idx) => {
    return this.indexOf(v, 0) === idx;
  });
}

// [
//   {},        {},
//   '',        233,
//   '233',     'abc',
//   undefined, null,
//   123,       [ 2 ],
//   [ 2 ],     [ 2, 3 ]
// ]

找出正数组中的最大差值

var arr = [10,5,11,7,8,9]; // 11-5=6

function getMaxProfit(arr) {
  var min = max = arr[0];
  for(var i = 0; i < arr.length; i++) {
    min = min <= arr[i] ? min : arr[i];
    max = max >= arr[i] ? max : arr[i];
  }
  return Math.abs(max - min);
}

🔥 从排序数组中删除重复项

// 若 nums = [1,1,2], 则函数应返回长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。
// 若 nums = [0,0,1,1,1,2,2,3,3,4], 则返回 5, 并且原数组被修改为 0, 1, 2, 3, 4。
var nums = [0,0,1,1,1,2,2,3,3,4];
function removeDuplicates(arr) {
  let len = arr.length;
  for (let i = 0; i < len; i++) {
    if (arr[i] === arr[i + 1]) {
      arr.splice(i, 1);
      i--;
      len--;
    }
  }
  return arr;
}
console.log(removeDuplicates(nums));

找出数组中出现次数最多的元素,并给出其出现过的位置

var arr = [1, 1, 2, 1, 10, 10, 11, 1, 7];
function fn(arr) {
  let hash = {};
  arr.forEach((v, idx) => {
    if (!hash[v]) {
      hash[v] = {
        target: v,
        idxs: [idx]
      }
    } else {
      hash[v].idxs.push(idx);
    }
  });
  let count = 0, ret = null;
  Object.values(hash).forEach(v => {
    if (v.idxs.length > count) {
      ret = v;
      count = v.idxs.length;
    }
  });
  return ret;
}
console.log(fn(arr));

🔥 将数组扁平化并去除其中重复数据,最终得到一个升序且不重复的数组

已知如下数组:

var arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];

编写一个程序将数组扁平化去并除其中重复部分数据,最终得到一个升序且不重复的数组

// ES6
// 扁平化数组
Array.prototype.flat = function() {
  return [].concat(...this.map(item => Array.isArray(item) ? item.flat() : [item]))
}
// 数组去重
Array.prototype.unique = function() {
  return [...new Set(this)]
}
// 数组排序
const sort = (a, b) => a - b;
console.log(arr.flat().unique().sort(sort));

// ES5
Array.prototype.flat = function() {
  return this.toString().split(',').map(v => Number(v));
}
Array.prototype.unique = function() {
  var obj = {}
  return this.filter((item, index) => {
    var tempItem = typeof item + JSON.stringify(item)
    return obj.hasOwnProperty(tempItem) ?
      false :
        obj[tempItem] = true
  })
}
const sort = (a, b) => a - b;
console.log(arr.flat().unique().sort(sort));

// ES5 或者
Array.prototype.flat = function() {
  return this.toString().split(',').map(v => Number(v));
}
function flat(arr) {
  let result = [];
  for (let i = 0; i < arr.length; i++) {
    const item = arr[i];
    if (item instanceof Array) {
      result.splice(result.length, 0, ...flat(item));
    } else {
      result.push(item);
    }
  }
  return result;
}
const sort = (a, b) => a - b;
console.log(flat(arr).unique().sort(sort));

🔥 使用迭代的方式实现 flatten 函数

迭代

let arr = [1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, 13]]]
const flatten = function(arr) {
  while (arr.some(v => Array.isArray(v))) {
     arr = [].concat(...arr)
  }
  return arr
}
console.log(flatten(arr));

递归

const flatten = function(arr) {
  return [].concat(...arr.map(v => Array.isArray(v) ? flatten(v) : v));
}
console.log(flatten(arr));

字符串拼接

function flatten(arr) {
  return arr.join(',').split(',').map(v => Number(v))
}

买卖股票的最佳时机

给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。

在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。

返回 你能获得的 最大 利润 。

示例 1:

输入:prices = [7,1,5,3,6,4]
输出:7
解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3。
最大总利润为 4 + 3 = 7 。

示例 2:

输入:prices = [1,2,3,4,5]
输出:4
解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4。
最大总利润为 4 。

示例 3: