Advanced-Frontend / Daily-Interview-Question

我是依扬(木易杨),公众号「高级前端进阶」作者,每天搞定一道前端大厂面试题,祝大家天天进步,一年后会看到不一样的自己。
https://muyiy.cn/question/
27.42k stars 3.29k forks source link

第 11 题:将数组扁平化并去除其中重复数据,最终得到一个升序且不重复的数组 #8

Open zpzxgcr opened 5 years ago

zpzxgcr commented 5 years ago

Array.from(new Set(arr.flat(Infinity))).sort((a,b)=>{ return a-b})

raul-taurus commented 5 years ago

Use recursion function

function recursiveUnwrapArray(array) {
    let list = [];
    array.forEach(element => {
        if (Array.isArray(element)) {
            recursiveUnwrapArray(element).forEach(e => list.push(e));
        } else {
            list.push(element);
        }
    });
    return list;
}

var arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10];
Array.from(new Set(recursiveUnwrapArray(arr))).sort((a, b) => a - b);
raul-taurus commented 5 years ago

 Flat by breadth-first

function flatArray() {
    let arrToFlat = arr;
    let flattedArr = [];
    let flatted = false;
    while (flatted === false) {
        flatted = true;
        for (const n of arrToFlat) {
            if (Array.isArray(n)) {
                flatted = false;
                for (const nn of n) {
                    flattedArr.push(nn);
                }
            }
            else {
                flattedArr.push(n);
            }
        }
        arrToFlat = flattedArr;
        flattedArr = [];
    }

    return arrToFlat;
}

var arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10];
Array.from(new Set(flatArray(arr))).sort((a, b) => a - b);
raul-taurus commented 5 years ago
function sortAndDedupe(arr) {
    let output = [];
    for (let index = 0; index < arr.length; index++) {
        for (let index2Compare = index + 1; index2Compare < arr.length; index2Compare++) {
            const element = arr[index];
            const element2Compare = arr[index2Compare];
            if (element > element2Compare) {
                arr[index] = element2Compare;
                arr[index2Compare] = element;
            }
        }
        if (output.length == 0 || output[output.length - 1] < arr[index]) {
            output.push(arr[index]);
        }
    }
    return output;
}

var arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10];
sortAndDedupe(arr.flat(Infinity));
LastStranger commented 5 years ago
var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
console.log([1].toString());
const newArr = [];
function f2(arr) {
    for(let each of arr){
        if(!Object.prototype.toString.call(each).includes('Array')){
            newArr.push(each);
        }else {
            f2(each)
        }
    }
}
f2(arr);
newArr.sort((pre, next) => {
    return pre - next;
});
const arr1 = new Set(newArr);
const finallyArr = Array.from(arr1);
console.log(finallyArr);

太厉害了,竟然想到用toString()解决多重数组的问题,flat我觉得不是题目的想表达的意思,我等屌丝只能老老实实用递归了.......

liuwenai commented 5 years ago

let arryn = ['1,3,2','1,89,37,4','1,4,2'] let m = arryn.toString().split(",").sort((a,b)=>{ return a-b}).map(Number) let n = [... new Set(m)] // 去重 console.log(n)

fariellany commented 5 years ago

arr.toString()。split(“,”)。sort((a,b)=> {return ab})

你可能后面需要 arr.toString().split(",").sort((a,b)=>{ return a-b}).map(Number) 不然数组元素都是字符串 结果并没有去重 还有两个2 5和12

你这样 还是没有去重呀 只是把字符串转换成了int类型而已 Array.from(new Set(arr.toString().split(",").sort((a,b)=>{ return a-b}).map(Number)))) 要去重还得加 Array.from(new Set) 这个语法 推荐 之前的语法 Array.from(new Set(arr.flat(Infinity))).sort((a,b)=>{ return a-b}) 很简洁方便

greatWeber commented 5 years ago

function flat(array) { return array.reduce((arr, val) => Array.isArray(val) ? arr.concat(flattenDeep(val)) : arr.concat(val), []); }; Array.from(new Set(flat(arr))).sort((a,b)=>{return a-b})

Cillivian commented 5 years ago
[...new Set(arr.flat(Infinity))].sort((a,b)=>{return a-b})

一句话怎么说

mySouler commented 5 years ago

var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]; function arrayHandle(arr){ let b = [] for(let i=0;i<arr.length;i++){ if(arr[i] instanceof Array){ b = b.concat(fn(arr[i])) }else{ if(b.indexOf(arr[i]) == -1){ b.push(arr[i]) } } } b = [...new Set(b)] b.sort(function(a,b){return a-b}) return b } arrayHandle(arr)

zzNire commented 5 years ago
function app(arr){  
    return [...(new Set(arr.toString().split(',')))].sort((x,y)=>x-y).map(x=>x-0);

}
shenxinle commented 5 years ago
function flat(arr) {
  let result = [];
  if (Array.isArray(arr)) {
    arr.forEach(item => {
      result = result.concat(flat(item));
    });
  } else {
    result = result.concat(arr);
  }
  return result;
}
function flatUniqueSort(arr) {
  let result = flat(arr);
  result.sort((a, b) => (a - b));
  return result.filter((v, i, arr) => v !== arr[i - 1]);
}

image

zhiweiweii commented 5 years ago
let arr = [[1,2,3,[5,6,7],[100,99,98,45,345,33]],[1,2,3],[12,1,[666,777,888,999]]]
let flatArr = [...new Set(arr.flat(Math.pow(2,53) - 1))].sort((a,b)=>a-b)
console.log(flatArr)
Carson126 commented 5 years ago
var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
var new_arr=arr.toString().split(",").sort((a,b)=>a-b);
// method1:
new_arr.map((v,i,s)=>{if(v === s[i-1]) s.splice(i,1); return v})
// method2:
new_arr = [...new Set(new_arr)];
MagicalBridge commented 5 years ago

看到很多朋友使用了Array.prototype.flat() 这个方法,查看了下MDN的文档,这个方法在IE下全系列都是不支持的,如果考虑到面试相关,是否需要做这个兼容性考虑。

// 数组扁平化
function flatten(arr){
  var result = [];
  for(var i = 0,len = arr.length;i<len;i++){
    if(Array.isArray(arr[i])){
      result = result.concat(flatten(arr[i]))
    }else{
      result.push(arr[i])
    }
  }
  return result
}
// 去重
function unique(resultArr){
  return [...new Set(resultArr)]
}
// 排序
function upSort(arr){
  return arr.sort(function(a,b){
    return a-b
  })
}
upSort(unique(flatten(arr)))
MagicalBridge commented 5 years ago

Array.from(new Set(arr.flat(Infinity))).sort((a,b)=>{ return a-b})

感谢提供思路,如果是面试题是否需要考虑 flat的兼容性问题

JerryGit1 commented 5 years ago

大佬们写法五花八门,一行就搞定了,学习了,我等菜鸟只能老老实实用递归。

image

listentolife commented 5 years ago

深度遍历:

let res = [];
function flatten (arr) {
  if (arr instanceof Array) {
    for (let item of arr) {
      flatten(item);
    }
  } else {
    res.push(arr);
  }
}
flatten(arr);
console.log([...new Set(res)].sort((a,b) => a-b));

广度遍历:

function flatten (arr) {
  let res = [];
  let stack = [...arr];
  while (stack.length) {
    let item = stack.shift();
    if (item instanceof Array) {
      stack.push(...item);
    } else {
      res.push(item);
    }
  }
  return res;
}
console.log([...new Set(flatten(arr))].sort((a,b) => a-b));

基于reduce:

function flatten (arr) {
  return arr.reduce((res,item) => item instanceof Array ? [...res, ...flatten(item)] : [...res,item], []);
}
console.log([...new Set(flatten(arr))].sort((a,b) => a-b));
Xu-Angel commented 5 years ago

题外话:任意深度平铺

const flatten = (arr, depth = 1) => arr.reduce((a, v) => a.concat(depth > 1 && Array.isArray(v) ? flatten(v, depth - 1) : v), [])
flatten([1, [2], 3, 4]); // [1, 2, 3, 4]
flatten([1, [2, [3, [4, 5], 6], 7], 8], 2); // [1, 2, 3, [4, 5], 6, 7, 8]
xgqfrms commented 5 years ago

MDN

flatten

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat

solution 1


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

let result = [...new Set(arr.flat(Infinity))].sort((a,b)=> a > b ? 1: -1);

console.log(`flat array with unique filter & sort`, result);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

solution 2

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

let result = Array.from(new Set(arr.flat(Infinity))).sort((a,b)=> a > b ? 1: -1);

console.log(`flat array with unique filter & sort`, result);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

solution 3

"use strict";

/**
 *
 * @author xgqfrms
 * @license MIT
 * @copyright xgqfrms
 * @created 2019-08-13
 *
 * @description 编写一个程序将数组扁平化去并除其中重复部分数据,最终得到一个升序且不重复的数组
 * @augments
 * @example
 * @link https://github.com/yygmind/blog/issues/43
 *
 */

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

let log = console.log;

const autoFlatArray = (arr = []) => {
    let result = [];
    const flatArray = (arr = []) => {
        for (let i = 0; i < arr.length; i++) {
            let item = arr[i];
            if (Array.isArray(item)) {
                let temp = flatArray(item);
                result.concat(temp);
            } else {
                result.push(item);
            }
        }
    };
    flatArray(arr);
    // filter & sort asc
    result = [...new Set(result)].sort((a, b) => a > b ? 1 : -1);
    return result;
};

let result = autoFlatArray(arr);

log(`result all =`, result);
// result all = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ]
Hi-yulin commented 5 years ago

Array.from(new Set(arr.flat(Infinity))).sort((a,b)=>{ return a-b}) 这里少了一点考虑,如果数组不是全数字型,类似[1,‘1’,2,‘2’],在new Set()的时候并不会去重。 在进行去重之前应该map(Number) Array.from(new Set(arr.flat(Infinity).map(Number))).sort((a,b)=>{ return a-b})

catbea commented 5 years ago

最优写法: const flatten = (arr) => arr.reduce((a, v) => a.concat(Array.isArray(v) ? flatten(v) : v), []); var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]; flatten(arr) //[1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]

Cillivian commented 5 years ago

排序和去重嘞嘻嘻

https://maas.mail.163.com/dashi-web-extend/html/proSignature.html?ftlId=3&name=%E6%9E%97%E6%B0%B4%E6%B3%89&uid=h2ojeremy%40hotmail.com&iconUrl=https%3A%2F%2Fmail-online.nosdn.127.net%2Fqiyelogo%2FdefaultAvatar.png&company=%E5%8D%8E%E5%8D%97%E7%90%86%E5%B7%A5%E5%A4%A7%E5%AD%A6&items=%5B%2215113597631%22%2C%22%E9%82%AE%E7%AE%B1%EF%BC%9Ah2ojeremy%40hotmail.com%22%5D [https://mail-online.nosdn.127.net/qiyelogo/defaultAvatar.png] 林水泉 华南理工大学 15113597631 邮箱:h2ojeremy@hotmail.com

签名由 网易邮箱大师https://mail.163.com/dashi/dlpro.html?from=mail88 定制

在2019年08月14日 16:37,catbeamailto:notifications@github.com 写道:

最优写法: const flatten = (arr) => arr.reduce((a, v) => a.concat(Array.isArray(v) ? flatten(v) : v), []); var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]; flatten(arr) //[1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]

— You are receiving this because you commented. Reply to this email directly, view it on GitHubhttps://github.com/Advanced-Frontend/Daily-Interview-Question/issues/8?email_source=notifications&email_token=AGJTQ32DEC3345U6NMOIZF3QEO735A5CNFSM4GWVPWIKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD4IDI2Q#issuecomment-521155690, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AGJTQ3YOKE6M5RTE2NYARLTQEO735ANCNFSM4GWVPWIA.

wsq815 commented 5 years ago

function flatten(arr, depth = 1) { //depth控制地迭代次数 return arr.reduce( (a,b) => a.concat(depth > 1 && Array.isArray(b) ? flatten(b, depth-1) : b), [] ) }

let result = flatten(arr,4); let a = Array.from(new Set(result)).sort((b,c) => b-c) console.log(a);

nspnemuri commented 5 years ago

[...new Set(arr.flat(4))].sort((a,b)=>a-b)

freya0608 commented 5 years ago

Array.from(new Set(arr.toString().split(',').map((v)=>{return parseInt(v,10)}))).sort((a,b)=>{ return a-b})

weixiaoxu123 commented 5 years ago

[... new Set(arr.toString().split(','))].sort((a,b)=>a-b)

yansideyu commented 5 years ago
arr.toString().split(",").sort((a,b)=>{ return a-b})

注意结果和原值对比一下,number类型变为string类型了;有人可能会说,最终结果转换为number不就行了,但如果原值中number和string同时存在的话呢

mouzhengjie commented 5 years ago

介绍一种基本的常规操作: var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]; var newArray = arr.toString().split(","); //newArray = ["1", "2", "2", "3", "4", "5", "5", "6", "7", "8", "9", "11", "12", "12", "13", "14", "10"] var tmpeList = []; for(var i = 0; i < newArray.length; i++) { if(tmpeList.indexOf(newArray[i]) == -1) { tmpeList.push(newArray[i]); } } //tmpeList =  ["1", "2", "3", "4", "5", "6", "7", "8", "9", "11", "12", "13", "14", "10"]; tmpeList.sort(function(a,b){return a-b;}); console.log(tmpeList); //tmpeList = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14"];

常规思路易于理解,但是明显代码量会比较多,多就会繁琐,繁琐就会容易出错,所以在平常的开发中,还是要多思考更优化的方案.

songguoguo927 commented 5 years ago

arr.toString().split(',').map(item=>+item).filter((item,index,array)=>{ return array.indexOf(item)===index; }).sort((a,b)=>a-b)

TheCityEmpty commented 5 years ago

我也来一个

function f (arr) { let rArr = [] arr.forEach(item => { if (Array.isArray(item)) { rArr.push(...f(item)) } else { rArr.push(item) } }) return [...new Set(rArr)].sort((a, b) => a - b) }

XJawher commented 5 years ago

const arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10];
let newArr = [];
// 需要写一个递归,直到数组中全部的元素都被 rest
const Recursive = (arr) => {
    arr.forEach(item => {
        if (Array.isArray(item) && item.some(ele => Array.isArray(item))) { // 子元素中还有数组,继续递归
            Recursive(item);
        } else if (Array.isArray(item)) { // 子元素中已经没有了数组
            newArr.push(...item);
        } else { // 只有单独的数字
            newArr.push(item);
        }
    });
};
Recursive(arr);
console.log(newArr.sort((a, b) => a - b)); // 升序
console.log([...new Set(newArr.sort((a, b) => a - b))]); // 去重

再观摩学习学习

1449829449 commented 5 years ago

骚写法 var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10].join() console.log(Array.from(new Set(arr.split(','))).sort((a,b)=>{ return a-b }))

Acring commented 5 years ago

请问数组降维在什么应用场景中使用比较好,学了这么多写法但是却想不到为什么要降维

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

var flatten = arr => {
   return arr.reduce((pre, cur) => {
    return [...new Set(pre.concat(Array.isArray(cur) ? flatten(cur) : cur))].sort((a, b) => a - b)
   }, [])
 }

 flatten(arr)
wgh815600709qq commented 5 years ago
Array.prototype.series = function () {
    if (this.length === 0) return this
    if (this.length === 1) {
        return Array.isArray(this[0]) ? this[0].series() : [this[0]]
    }
    return this.reduce((res, next) => {
        return [res].series().concat([next].series())
    })
}

Array.prototype.noRepeatItem = function() {
    return Array.from([...new Set(this)])
}

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

arr.series ().noRepeatItem().sort((a,b) => a - b)
Equis17 commented 5 years ago

[... new Set(arr.flat(Infinity).sort((a,b)=>a-b))]

wangsixiao commented 5 years ago
const arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];

// 化为一维数组
// 方法一:化为字符串处理
let flagArr = arr.join()
        .split(",")
        .map(item => Number(item))
// 方法二: reduce方法
    let flagFunc = (arr) => {
        return arr.reduce((total, cur) => 
            total.concat(Array.isArray(cur) ? flagFunc(cur) : cur), []
        )
    }
    let flagArr = flagFunc(arr)

// 去重
let noRepeatArr = [...new Set(flagArr)]

// 升序排序
function compare(a, b) {
    return a - b
}
let result = noRepeatArr.sort(compare)

console.log(result)
always-in commented 5 years ago

`

let temp = arr.toString().split(',').map(item => parseInt(item))

let tempSet = new Set(temp) // 去重

temp = [...tempSet]

return temp;

`

angeliaz commented 5 years ago

const arr = [[1, 2, 2, 0, -1], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10] Array.from(new Set(arr.toString().split(',').map(Number).sort((a, b)=>a-b)))

aeolusheath commented 5 years ago

扁平化数组

递归


 var flat = (arr, res) => {
  var result = res || []
  arr.forEach(item => {
    var r = Array.isArray(item) ? flat(item, []) : item
    result= [].concat(result, r)
  })
  return result
}

数组内在方法


var flag = (arr) => {
  return arr.toString().split(',').map(Number)
}

数组去重

用Set

var unique = (arr) => {
  return [...new Set(arr)]
}

用Map

...略

ZhChen7 commented 5 years ago

Array.from(new Set(arr.toString().split(','))).sort((a,b)=>{return a-b}).map(Number) 或者 Array.from(new Set(arr.flat(Infinity))).sort((a,b)=>{ return a-b})

ScholatLouis commented 5 years ago
function flattern(arr) {
    let input = [...arr];
    let res = [];
    while(input.length) {
        let next = input.pop();
        if(Array.isArray(next)) {
             input.push(...next);
        } else {
            res.push(next);
        }
    }
    return res.reverse();
}
ScholatLouis commented 5 years ago
function flatternDepth(arr, depth) {
    let input = [...arr];
    let res = [];
    let count = 0;
    while(input.length) {
        let next = input.pop();
        if(Array.isArray(next) && count < depth) {
            input.push(...next);
            ++count;
        } else {
            res.push(next);
            count = 0;
        }
    }
    return res.reverse();
}
DavidChen93 commented 5 years ago

第一想法是递归,结果看到大佬们一个个都贼强 function Recursive(data, result) { if (Object.prototype.toString.call(data) === '[object Array]') { data.forEach(item => { console.log(item) Recursive(item, result) }) } else { result.push(data) } }

function serialArray(array) { let result = [] array.forEach(item => { Recursive(item, result) }) return Array.from(new Set(result)).sort((a, b) => a - b) }

let arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10] console.log(serialArray(arr))

JohnieXu commented 5 years ago

ES6原生数组扁平化函数https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat

hongz1125 commented 5 years ago

var arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10]; function clearReapt(ary){ let flat = (ary) => { return ary.reduce((sam, item) => Array.isArray(item) ? sam.concat(flat(item)) : sam.concat(item), []) } return Array.from(new Set(flat(arr))).sort((a, b) => a - b); } console.log(clearReapt(arr))

RomanHc commented 5 years ago
const flatDeep = arr => arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flatDeep(val) : val), []);
const sort = (a, b) => a - b;
const arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
console.log( [...new Set(flatDeep(arr))].sort(sort));
Longgererer commented 5 years ago
arr.toString().split(",").sort((a,b)=>{ return a-b})

可以这样:

Array.from(new Set(arr.toString().split(',').map(Number).sort((a, b)=>(a - b))))

可以在sort之前使用map把string转换成number类型,先使用sort会造成隐式类型转换,虽然结果一样,但感觉不太好

wanwenyun commented 5 years ago
var res = Array.from(new Set(arr.join().split(","))).sort((a,b)=>{return a-b}).map(Number);

1615_0

Fengzhen8023 commented 5 years ago

小菜鸡的回答

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

// 使用递归函数,扁平化数组
flat(arr);

// 使用ES6语法,去重
result = Array.from(new Set(result))

// 对数组进行排序
result.sort((a, b) => {
    return a - b;
})

// 打印最终结果
console.log(result)

function flat(arr) {
    for(var item of arr) {
        if (item instanceof Array) {
            flat(item)
        } else {
            result.push(item)
        }
    }
}