导航


HTML

CSS

JavaScript

浏览器 & 网络

版本管理

框架

构建工具

TypeScript

性能优化

软实力

算法

UI、组件库

Node

冷门技能

针对性攻坚(TODO)

刷题


数组的常用方法有哪些?

方法 作用 是否影响原数组
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: