多维数组降维
基础写法:需要额外变量 递归
var result=[]
var flat=function (arr) {
for(let i=0;i<arr.length;i++){
if(Array.isArray(arr[i])){
flat(arr[i])
}else{
result.push(arr[i]);
}
}
}
var list=[1,2,[[3,4,5],6],[7,8],[9]];
flat(list);
console.log(result) //[1,2,3,4,5,6,7,8,9]
函数式写法(推荐):
var flat=function (arr) {
var result=[]
for(let i=0;i<arr.length;i++){
if(Array.isArray(arr[i])){
result=result.concat(flat(arr[i]))
}else{
result.push(arr[i]);
}
}
return result;
}
var list=[1,2,[[3,4,5],6],[7,8],[9]];
console.log(flat(list))
//延伸:将改方法绑定到数组的原型链上,arr换成this
Array.prototype.flatten=function () {
var result=[]
for(let i=0;i<this.length;i++){
if(Array.isArray(this[i])){
result=result.concat(this[i].flatten())
}else{
result.push(this[i]);
}
}
return result;
}
字符串式写法
var flat=function(arr){
let strarr=arr+"";
let str=strarr.split(",");
return str;
}
究极写法:
let flatten = arr => arr.reduce((begin,current)=>{
Array.isArray(current)?begin.push(...flatten(current)):begin.push(current);
return begin
},[])
数组去重的五种方法:
- Array.filter() + indexOf
function deRepeat1(nums) {
let res=[]
res=nums.filter((item,index)=>{
return nums.indexOf(item)===index
})
return res;
}
- for...of + includes()
function deRepeat2(nums) {
let res=[]
for(let item of nums){
!res.includes(item)&&res.push(item)
}
return res;
}
- 双重 for 循环
function deRepeat3(nums) {
let res=[]
for(let i=0;i<nums.length;i++){
for(let j=0;j<nums.length;j++){
if(nums[j]==nums[i]&&i==j){
res.push(nums[i])
break;
}
}
}
return res;
}
- Array.sort()
function deRepeat4(nums) {
let res=[]
let arr=nums.sort()
for(let i=0;i<arr.length-1;i++){
if(arr[i]!==arr[i+1]) res.push(arr[i])
}
res.push(arr[arr.length-1])
return res;
}
- for...of + Object (推荐)
function deRepeat5(nums) {
let res=[]
let obj={}
for(let item of nums){
if(!obj[item]){
res.push(item);
obj[item]=1;
}
}
return res;
}
- ES6的new Set() (推荐)
function deRepeat6(nums) {
return Array.from(new Set([...nums]));
}
实现数组原型方法
forEach
Array.prototype.forEach2 = function(callback, thisArg) {
if (this == null) {
throw new TypeError('this is null or not defined')
}
if (typeof callback !== "function") {
throw new TypeError(callback + ' is not a function')
}
const O = Object(this) // this 就是当前的数组
const len = O.length >>> 0 // 后面有解释
let k = 0
while (k < len) {
if (k in O) {
callback.call(thisArg, O[k], k, O);
}
k++;
}
}
O.length >>> 0 是什么操作?就是无符号右移 0 位,那有什么意义嘛?就是为了保证转换后的值为正整数。其实底层做了 2 层转换,第一是非 number 转成 number 类型,第二是将 number 转成 Uint32 类型
map
Array.prototype.map2 = function(callback, thisArg) {
if (this == null) {
throw new TypeError('this is null or not defined')
}
if (typeof callback !== "function") {
throw new TypeError(callback + ' is not a function')
}
const O = Object(this)
const len = O.length >>> 0
let k = 0, res = []
while (k < len) {
if (k in O) {
res[k] = callback.call(thisArg, O[k], k, O);
}
k++;
}
return res
}
filter
Array.prototype.filter2 = function(callback, thisArg) {
if (this == null) {
throw new TypeError('this is null or not defined')
}
if (typeof callback !== "function") {
throw new TypeError(callback + ' is not a function')
}
const O = Object(this)
const len = O.length >>> 0
let k = 0, res = []
while (k < len) {
if (k in O) {
if (callback.call(thisArg, O[k], k, O)) {
res.push(O[k])
}
}
k++;
}
return res
}
some
Array.prototype.some2 = function(callback, thisArg) {
if (this == null) {
throw new TypeError('this is null or not defined')
}
if (typeof callback !== "function") {
throw new TypeError(callback + ' is not a function')
}
const O = Object(this)
const len = O.length >>> 0
let k = 0
while (k < len) {
if (k in O) {
if (callback.call(thisArg, O[k], k, O)) {
return true
}
}
k++;
}
return false
}
reduce
Array.prototype.reduce2 = function(callback, initialValue) {
if (this == null) {
throw new TypeError('this is null or not defined')
}
if (typeof callback !== "function") {
throw new TypeError(callback + ' is not a function')
}
const O = Object(this)
const len = O.length >>> 0
let k = 0, acc
if (arguments.length > 1) {
acc = initialValue
} else {
// 没传入初始值的时候,取数组中第一个非 empty 的值为初始值
while (k < len && !(k in O)) {
k++
}
if (k > len) {
throw new TypeError( 'Reduce of empty array with no initial value' );
}
acc = O[k++]
}
while (k < len) {
if (k in O) {
acc = callback(acc, O[k], k, O)
}
k++
}
return acc
}
深拷贝浅拷贝
JSON方法实现
//深拷贝
JSON.stringify() & JSON.parse()
//缺点:拷贝对象包含正则,函数,或者undefined时会失效
let obj = { a: 1, b: { x: 3 } };
// let obj2 = JSON.parse(JSON.stringify());
递归实现
function deepClone(obj) {
let res = obj instanceof Array ? [] : {};
for (let i in obj) {
if (obj.hasOwnProperty(i)) {
res[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i];
}
}
return res;
}
多维数组每一维排列组合
var result = [];
var results = [];
var doExchange = function (arr, depth) {
for (let i = 0; i < arr[depth].length; i++) {
result[depth] = arr[depth][i];
if (depth !== arr.length - 1) {
doExchange(arr, depth + 1);
} else {
results.push(result.join("").split(""));
}
}
};
doExchange([[1, 2, 3],[4, 5],[6, 7]],0);
// [ 1, 4, 6 ],
// [ 1, 4, 7 ],
// [ 1, 5, 6 ],
// [ 1, 5, 7 ],
// [ 2, 4, 6 ],
// [ 2, 4, 7 ],
// [ 2, 5, 6 ],
// [ 2, 5, 7 ],
// [ 3, 4, 6 ],
// [ 3, 4, 7 ],
// [ 3, 5, 6 ],
// [ 3, 5, 7 ]