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})

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

[...new Set(arr.flat(Infinity))].sort((x,y)=>x-y)

tywei90 commented 5 years ago

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

huangtiandi1999 commented 5 years ago

都用了flat,那我写个polyfill的 function flattenSort(arr) { let flat = function (array) { return array.reduce((pre, cur) => { return Array.isArray(cur) ? [...pre, ...flat(cur)] : [...pre, cur]; }, []); }

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

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

上面的未去重,增加去重:

Array.from(new Set(arr.toString().split(','))).sort((a, b) => a-b)
huaipomen commented 4 years ago

// 得到一个升序且不重复的数组 // 迭代思想

var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]; function* formatter(arr){ if(Array.isArray(arr)){ arr.forEach(item=>{ yield* formatter (item) }) }else{ yield arr } } console.log( [...new Set(formatter(arr))].sort((n1,n2)=>n1-n2))

feitingting commented 4 years ago

arr.toString().split(",").reduce(function(prev,current){ if(!prev.includes(Number(current))){ prev.push(Number(current)); } return prev; },[]).sort((a,b)=>{return a-b})

qiaoqiao10001 commented 4 years ago

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

qiaoqiao10001 commented 4 years ago
let arrs = Array.from(new Set(arr.flat(Infinity)))
arrs.sort(function(a,b){return a-b})
cpg0525 commented 4 years ago
const deepFlat = arr => [...new Set(arr.reduce((acc, cur) => acc.concat(Array.isArray(cur) ? deepFlat(cur) : cur), []))].sort((a, b) => a - b);
wangjunjun0212 commented 4 years ago

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

function lists(arr,newArrs = []) {
  /**
  * 设定默认返回的新数组,确定不污染原来的数组
  * 验证传入的数组必须有效,才进行数组扁平化,去重,排序
  **/
  let length = arr ?  arr.length >>> 0 : arr >>> 0
  if(length == 0)
    return newArrs
  else 
    for(let i = 0; i < length; i++) {
      arr[i].length > 0 ? lists(arr[i],newArrs) : (newArrs.indexOf(arr[i]) === -1 && newArrs.push(arr[i]))
    }
  return newArrs.sort((a, b) => a - b)
}

console.log(lists(arrs)) //[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

// 增强代码的复用性及性能,才是我们每个IT从业者所追求的,而不仅仅只是为了解决目前所存在的问题而解决

gaoxinxiao commented 4 years ago
var arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10];
    function FormtArr(arr, newArr=[]) {
        arr.map(item => {
            if (Array.isArray(item)) {
                FormtArr(item, newArr);
            } else {
                !newArr.includes(item) && newArr.push(item)
            }
        })
        return newArr.sort((a, b) => a-b);
    }
//通俗易懂
yygmind commented 4 years ago

测试用例:

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

function flattern(arr,resultArr = []) { if(arr instanceof Array && arr.length > 0) { arr.forEach(value => { if(value instanceof Array && value.length > 0) { flattern(value,resultArr) } else { if(resultArr.indexOf(value) === -1) resultArr.push(value) } }) } return resultArr.sort((a,b) => a-b) }

SnailOwO commented 4 years ago

const flattenDeep = (ary) => Array.isArray(ary) ?
        ary.reduce((a, b) => [...a, ...flattenDeep(b)], []) : [ary];

    function demo(ary) {
        let flatAry = flattenDeep(ary);
        if (!flatAry.length) {
            return [];
        } else {
            return [...new Set(flatAry)].sort((a, b) => {
                return a - b;
            });
        }
    }
suiyuex commented 4 years ago

想了一下写的答案

Array.from(new Set(arr.flat(Infinity))).sort((a,b)=>a>b)
ningyahai commented 4 years ago
var  deal=function(arr){
                //将数组进行扁平化处理
                let a1=arr.join(',').split(',');
                let obj={};
                //去除重复后的新数组
                let new_arr=[];
                for(let i=0;i<a1.length;i++){
                    if(obj[a1[i]]==undefined){
                        obj[a1[i]]=1;
                        new_arr.push(a1[i]);
                    }
                }
                //排序
                new_arr.sort(sortNumber);
                //升序且不重复的数组
                return new_arr;
            }
            var sortNumber=function(a,b){
                return a-b
            }
bosens-China commented 4 years ago

第一个回答有点取巧,建议写两种方式,第一种就是上面的,第二种则是手写flat和去重

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

let res = [];
while (arr.length > 0) {
    [...arr].forEach(item => {
        item = arr.shift()
        if (Array.isArray(item)) {
            arr.push(...item)
        } else {
            res.push(item)
        }
    });
}

for (let i = 0; i < res.length - 1; i++) {
    for (let j = i; j < res.length; j++) {
        if (res[j] > res[j + 1]) {
            [res[j], res[j + 1]] = [res[j + 1], res[j]]
        }
    }
}

console.log(...new Set(res));
zhcxk1998 commented 4 years ago

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

bosens-China commented 4 years ago

原生调用的第一个答案已经写了,下面我也写一个手动实现的版本

flot

function flot(par) {
    for (let i = 0; i < par.length; i++) {
        const value = par[i];
        if (Array.isArray(value)) {
            par.splice(i, 1, ...(flot(value)));
        }
    }
    return par;
}

排序和去重简单,直接用排序后的数组对比下一个数组的值,如果相同肯定是存在了

去重和排序

function unique(par) {
    const value = [];
    const sort = par.sort((x, y) => x - y);
    for (let i = 0; i < sort.length; i++) {
        const v = sort[i];
        if (v !== sort[i + 1]) {
            value.push(v);
        }
    }
    return value;
}

使用

let v = [[4, [55, [66]]], 1, 2, [3, 4], 5, [[7, 8]]];
v = unique(flot(v));
console.log(v);
alt1o commented 4 years ago

function test(arr, ret){ if(ret === undefined) ret = []; for(let i = 0; i < arr.length; i++){ if(Array.isArray(arr[i])){ test(arr[i], ret); }else{ if(ret.indexOf(arr[i]) === -1){ let j = 0; while(j < ret.length && arr[i] > ret[j]){ j++; } ret.splice(j, 0, arr[i]); } } } return ret; }

zhangwinning commented 4 years ago

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

RomeoChen commented 4 years ago

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

image image

Mr-syc commented 4 years ago

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

Caleb-Xu commented 4 years ago

暴力写法 [...new Set(arr.toString().split(',').map(i=>+i).sort((a,b)=>a-b))]

miser commented 4 years ago
function compare(arr, rest) {
  for (var i = 0; i < arr.length; i++) {
    const index = arr[i] - 1;
    if (Array.isArray(arr[i])) {
      compare(arr[i], rest);
    } else if (rest[index] === false) {
      rest[index] = true;
    }
  }
}

function main(arr) {
  const temp = new Array(14).fill(false);
  compare(arr, temp);
  const rest = [];
  temp.forEach((val, index) => {
    if (val === true) rest.push(index + 1);
  });
  return rest;
}

const rest = main(arr);
rookiebulls commented 4 years ago

写个generator版的

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

function *flat(arr) {
    for (const item of arr) {
        if (Array.isArray(item)) {
            yield* flat(item)
        } else {
            yield item
        }
    }
}

var flatArr = flat(arr)
console.log(...new Set([...flatArr].sort((a,b) => (a - b))))
wangyang310 commented 4 years ago

来一个不使用原生API的方法

var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
// 拍平
function flatten (arr) {
    return arr.reduce((prev, curr) => {
        return Array.isArray(curr) ? [...prev, ...flatten(curr)] : [...prev, curr]
    }, [])
}
// 去重
function unique (arr) {
    return arr.filter((val, idx, arr) => arr.indexOf(val) === idx)
}
// 冒泡排序
function sort (arr) {
    for (let i = 0; i < arr.length - 1; i++) {
        for (let j = 0; j < arr.length - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]
            }
        }
    }
    return arr
}

let arr1 = sort(unique(flatten(arr)))
console.log(arr1)
LiZhaoYangClub commented 4 years ago

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

moronghui commented 4 years ago

很多童鞋喜欢用Set、Array.prototype.flat。 而这就是最优答案吗? 是否考虑过性能? 本人写了个博客,欢迎指正和交流:https://juejin.im/post/5e6db6fbe51d4527214bcbd2

helloforrestworld commented 4 years ago
function flat(arr) {
  while(arr.some(item => Array.isArray(item))) {
    arr = [].concat(...arr)
  }
  arr = [...new Set(arr)]
  arr.sort((a, b) => a - b)
  return arr
}
Albert-cord commented 4 years ago
function flattenSort(arr, fn) {
    function flatten(arr) {
        return arr.reduce((pre, next) => {
            if(Array.isArray(next)) {return pre.concat(flatten(next));}
            else {
                if(!isNaN(next)) {
                    return pre.concat(next);
                }
            }
            return pre;
        }, []);
    }
    return [...new Set(flatten(arr))].sort(fn || ((a, b) => a - b));
}
flattenSort([ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ],[NaN, NaN, 13.5, 15] ] ], 10])

考虑NaN的情况

aimeefe commented 4 years ago

let r = [...new Set(arr.flat(Infinity))].sort((a, b) => a - b)] console.log(r) // 输出:[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

zuoyi615 commented 4 years ago
const arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10]
const flatten3 = arr => arr.reduce((pre, item) => pre.concat(Array.isArray(item) ? flatten3(item) : item), [])
flatten3(arr)
BiYangJun commented 4 years ago

var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]; var reslut = [...new Set(arr.flat(4))].sort((a, b)=>a-b)

wangmeijian commented 4 years ago

既然是算法题,就要考虑性能而不是直接套API,参考思路:

  1. 扁平化数组并去重:将数组toString,然后找出全部数字组成一维数组,利用map格式去重
  2. 排序:排序算法有很多种,就这个题而言,数字基本有序,用插入排序比较快
    
    const arr = [
    [1, 2, 2],
    [3, 4, 5, 5],
    [6, 7, 8, 9, [11, 12, [12, 13, [14]]]],
    10,
    ];
    const map = {};

arr.toString().replace(/-?\d+/g, function (n) { if (n in map) return n; map[n] = Number(n); }); let res = []; res = Object.values(map) console.log(res); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

本题所有数字都是正数,Object.keys(map)输出的数组会自动排序  
但还是尽量不要依赖Object.keys()的输出顺序,[背后的原理](https://github.com/wangmeijian/blog/blob/master/docs/Object.values()%E6%8E%92%E5%BA%8F%E9%9D%A0%E8%B0%B1%E5%90%97.md)
老老实实排序吧  
```js
let i, j;
for (i = 1; i < res.length; i++) {
  key = res[i]
  j = i - 1;
  while (j >= 0 && res[j] > key) {
    res[j + 1] = res[j];
    j--;
  }
  res[j + 1] = key;
}
console.log(res);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
dw-beige commented 4 years ago

原题中的Infinity是用来干什么的

参数: 表示可以展开任意深度的数组

UnrealCherry commented 4 years ago

let set =new Set() function flattenArraysAndDeDuplicates(array) { array.forEach((x, i, a) => { if (Object.prototype.toString.call(x) == '[object Array]') { flattenArraysAndDeDuplicates(x) } else { set.add(x)
} }) return set.sort((a,b)=>{ return a-b}) } 用的递归思想 看了答案没想到还有这么简单的答案 和 flat 这个函数

jdkwky commented 4 years ago

Array.from(new Set(JSON.stringify(list).replace(/([|])/g, '').split(",").sort((a, b) => { return a - b }).map(Number)))

larry-hsu commented 4 years ago
Array.prototype.flattern = function () {
  let arr = [...this];
  var res = [];
  while(arr.length) {
    var tmp = arr.pop();
    if (Array.isArray(tmp)) {
      arr.push(...tmp)
    } else {
      res.unshift(tmp);
    }
  }
  return res;
}

Array.prototype.unique = function () {
  return this.filter((item, index) => this.indexOf(item) === index);
}

arr.flattern().unique().sort((a, b) => a-b)
tangzhibao commented 4 years ago
const arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]

const flatSort = arr => Array.from(new Set(arr.flat(Infinity))).sort((a, b) => a - b)

只是来交作业,应该就是和up一样最简答案了。

lunhui1994 commented 4 years ago

数组扁平化处理:

const arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]
const flatArr = (arr + '').split(',');

数组去重:利用数组indexOf一直返回首次出现的位置的原理

flatArr = flatArr.filter((item, key, arr) => {
  return arr.indexOf(item) === key;
})

数组排序:归并排序

function gb(left, right, arr) {
            if (left === right) {return;}
            let mid = left + ((right-left) >> 1);
            gb(left, mid, arr);
            gb(mid+1, right, arr);
            let help = [];
            let leftIndex = left;
            let rightIndex = mid + 1;
            while(leftIndex <= mid && rightIndex <= right) {
                help.push(arr[leftIndex] <= arr[rightIndex] ? arr[leftIndex++] : arr[rightIndex++])
            }
            while(leftIndex <= mid) {
                help.push(arr[leftIndex++])
            }
            while(rightIndex <= right) {
                help.push(arr[rightIndex++])
            }
            arr.splice(left, right-left+1,...help)
            return arr;
        }
arr = gb(0, arr.length -1, arr);
yakey commented 4 years ago

[...new Set(arr.flat(Infinity).sort(function(a,b){return a-b}))] 或者 Array.from(new Set(arr.flat(Infinity).sort(function(a,b){return a-b})))

long-joan commented 4 years ago

function f(arr) { const obj = {} const b = [] const c = [] for (let i = 0; i < arr.length; i++) { if (Object.prototype.toString.call(arr[i]) === '[object Array]') { arr = arr.concat(arr[i]) } else { c.push(arr[i]) } } for (let j = 0; j < c.length; j++) { const f = c[j]; if (!obj[f]) obj[f] = f; b.push(f) } return b.sort((h, n) => h - n) }

alvin-xin commented 4 years ago

原题中的Infinity是用来干什么的

用 Infinity 作为深度,展开任意深度的嵌套数组

cutie6 commented 4 years ago

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

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

map 也没有做到去重啊

zhangxuyang950313 commented 4 years ago
Array.from(new Set(arr.flat(4))).sort((a, b) => a-b)
cutie6 commented 4 years ago

这题目名字改成 “数组扁平、去重、升序排列” 更好吧,不然标题看不出来是什么题目

chenxinxia commented 4 years ago

不用ES6的简陋版

function flat (arr) {
    let result = []
    while (arr.length) {
        let temp = arr.shift()
        if (Array.isArray(temp)) {
            arr.unshift.apply(arr, temp)
        } else {
            result.push(temp)
        }
    }
    return result
}
function removeDuplicate(arr) {
    let temp = {}
    let result = []
    for (let i = 0; i < arr.length; i++) {
        if (!temp[arr[i]]) {
            temp[arr[i]] = 1
            result.push(arr[i])
        }
    }
    return result
}
removeDuplicate(flat([[ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]])).sort((a, b) => a - b) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]