Daily-Interview-Question icon indicating copy to clipboard operation
Daily-Interview-Question copied to clipboard

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

Open zpzxgcr opened this issue 5 years ago • 382 comments

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

zpzxgcr avatar Feb 12 '19 00:02 zpzxgcr

image

zpzxgcr avatar Feb 12 '19 01:02 zpzxgcr

相关知识点

es6数组常用操作

zpzxgcr avatar Feb 12 '19 01:02 zpzxgcr

arr.toString().split(",").sort((a,b)=>{ return a-b})

hejiaqian avatar Feb 12 '19 01:02 hejiaqian

image

hejiaqian avatar Feb 12 '19 01:02 hejiaqian

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

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

zpzxgcr avatar Feb 12 '19 01:02 zpzxgcr

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

你可能后面需要 arr.toString().split(",").sort((a,b)=>{ return a-b}).map(Number) 不然数组元素都是字符串

谢谢大佬指点,学习了

hejiaqian avatar Feb 12 '19 01:02 hejiaqian

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)); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ]

cjfff avatar Feb 12 '19 01:02 cjfff

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

    while (arr.some(item => Array.isArray(item))) {
        arr = [].concat(...arr);
    }

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

AprilTong avatar Feb 12 '19 02:02 AprilTong

Array.prototype.falt = function() {
    return [].concat(...this.map(item => (Array.isArray(item) ? item.falt() : [item])));
}

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

const sort = (a, b) => a - b;

console.log(arr.falt().unique().sort(sort)); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ]

函数名应该是flat

zpzxgcr avatar Feb 12 '19 02:02 zpzxgcr

Array.prototype.falt = function() {
    return [].concat(...this.map(item => (Array.isArray(item) ? item.falt() : [item])));
}

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

const sort = (a, b) => a - b;

console.log(arr.falt().unique().sort(sort)); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ]

函数名应该是flat

  • -感谢斧正

cjfff avatar Feb 12 '19 02:02 cjfff

var old_arr=[ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
		
// 数组拍平
var level_arr=old_arr.flat(4);

//数组去重
var Distinct=Array.from(new Set(level_arr));

// 排序
var sort=  Distinct.sort((a, b) =>a - b)

console.log("new arr",sort)

w587 avatar Feb 12 '19 02:02 w587

递归函数解法:

function spreadArr(arr=[]){
	if(arr.some(ele=>Array.isArray(ele))){
		let newArr = [];
		arr.forEach((ele) => {
			if(Array.isArray(ele)){
				newArr = newArr.concat(...ele)
			}else{
				if(!newArr.includes(ele)) newArr.push(ele)
			}
		})
		return spreadArr(newArr);
	}
	return arr.sort((a,b)=> a-b);
}
spreadArr([ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]);

jackchenl avatar Feb 13 '19 06:02 jackchenl

利用前面的答案,修正一个没用ES6的写法:

// 1、扁平化数组 var flatArr = arr.toString().split(","); // 2、去重 var hash = {}; for (var i = 0, len = flatArr.length; i < len; i++) { hash[flatArr[i]] = "abc" } flatArr = []; // 3、将元素字符串转化为数字、遍历hash并不能保证输出顺序 for (var i in hash) { flatArr.push(+i) } // 4、排序 flatArr = flatArr.sort(function(a, b) { return a - b }) console.log(flatArr)

zhuzhuoxingguang avatar Feb 14 '19 01:02 zhuzhuoxingguang

看一道面试题:

已知如下数组:var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];

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

答案:

var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]
// 扁平化
let flatArr = arr.flat(4)
// 去重
let disArr = Array.from(new Set(flatArr))
// 排序
let result = disArr.sort(function(a, b) {
    return a-b
})
console.log(result)
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

关于 Set 请查阅 Set、WeakSet、Map及WeakMap

本文首发于我的博客:数组扁平化、去重、排序

sisterAn avatar Feb 16 '19 09:02 sisterAn

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

xiaoluoboding avatar Feb 18 '19 02:02 xiaoluoboding

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

wangweianger avatar Feb 18 '19 02:02 wangweianger

额 虽然没大佬们厉害,暂且做个记录吧


function flap(arr){
  if([].every.call(arr,item=>!Array.isArray(item))){
    return arr; 
  }
  return [].reduce.call(arr,(pre,cur)=>{
    if(Array.isArray(cur)){
      return [].concat(pre,flap(cur));
    }else{
      return [].concat(pre,cur);
    }
  },[])
}

function removeRepeat(arr){
  return [...new Set(arr)];
}

function sort(arr){
  return [].sort.call(arr,(a,b)=>a-b)
}

function handle(data,...fns){
  return fns.reduce((pre,cur)=>{
      return cur(pre);
  },data)
}

handle(arr,flap,sort,removeRepeat);

Allen3039 avatar Feb 18 '19 12:02 Allen3039

arr.join(','),split(','),sort((a,b) => a - b)

xpbsm avatar Feb 18 '19 15:02 xpbsm

拍平: const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v))); 用toString会改变数组里面的原始数据,应该会是扣分项。

mydaoyuan avatar Feb 19 '19 01:02 mydaoyuan

1550544432 1

ihuoge avatar Feb 19 '19 02:02 ihuoge

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

Jason686 avatar Feb 19 '19 06:02 Jason686

  1. 拍平数组:const flatArray = arr => arr.reduce((a,b) => a.concat(Array.isArray(b) ? flatArray(b): b), []);
  2. 去重+排序: [...new Set(flatArray)].sort((a,b) => a-b);

hellojackhui avatar Feb 19 '19 06:02 hellojackhui

image

fan-2 avatar Feb 19 '19 07:02 fan-2

var arr = [...new Set(arr.join(',').split(','))].map(v => Number(v)).sort((a,b) => a-b)

yishuihan-001 avatar Feb 19 '19 07:02 yishuihan-001

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

  var obj = {};
  function arrDef(arr) {
      if(arr instanceof Array){
        arrforDef(arr)
      }else {
        obj[arr] = 1;
      }
  }

  function arrforDef(arr){
    arr.forEach( function(element, index) {
       arrDef(element)
    });
  }

 
  arrDef(arr);
  console.log(Object.keys(obj))

xiaochen111 avatar Feb 20 '19 02:02 xiaochen111

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

mySouler avatar Feb 20 '19 07:02 mySouler

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

function flat (arr) {
  function toFlat (acc, current) {
    if (Object.prototype.toString.call(current) === '[object Array]') {
      current.forEach(item => {
        toFlat(acc, item)
      })
    } else {
      if (!acc.includes(current)) {
        acc.push(current)
      }
    }
    return acc
  }
  return arr.reduce(toFlat, []).sort((value1, value2) => value1 - value2)
}

flat(arr)

利用Array.prototype.reduce函数递归进行函数拍平去重加排序。这个咋样?

Liubasara avatar Feb 20 '19 09:02 Liubasara

// 已知如下数组: var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10 ]; // 编写一个程序将数组扁平化去并除其中重复部分数据,最终得到一个升序且不重复的数组

    // // 去扁平化
    function paiping(arr){
        if(Array.isArray(arr)){
            let arr_ = [];
            digui(arr,arr_);
            return arr_;
        }
    }
    // 递归
    function digui(arr_item,arr_){
        for(let i=0;i<arr_item.length;i++){
                if(Array.isArray(arr_item[i])){
                    digui(arr_item[i],arr_);
                }else{
                    arr_.push(arr_item[i]);
                }
            }
    }
    let res =[...new Set(paiping(arr).sort((a,b)=>a-b))];
    console.log(res);
    // 方法二
   let res2 =[...new Set(arr.toString().split(",").map((items)=>{
      return parseInt(items);
   }).sort((a,b)=>a-b))] ;
   console.log(res2);

weiweixuan avatar Feb 20 '19 09:02 weiweixuan

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

xifenzs avatar Feb 20 '19 09:02 xifenzs

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

xiangergou avatar Feb 20 '19 14:02 xiangergou

个人拙见:

function flatten(arr) {
  return arr.reduce(function (flat, toFlatten) {
    return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);
  }, []).sort((a, b) => a - b).filter (function (value, index, array) { 
    return array.indexOf (value) == index;
});
}

image

chiwent avatar Feb 21 '19 13:02 chiwent

我觉得最好不要在 built-in 函数的 prototype 上直接加方法 而且有些方法命名不太规范,比如 const sort = (a, b) => a - b;,我觉得命名为 comparator 比较合理。另外,还有函数命名为 flatten,我觉得 flat 可能会更好


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

toString 用在这里确实不太合适。因为 tostring 会把数组里面的元素会变成 string 类型。比如,对象类型的数组元素({a: 1})会变成 [object Object] 以及函数类型的数组元素(new Function('a', 'b', 'return a - b'))会变成 function anonymous(a,b) {return a - b}

ghost avatar Feb 22 '19 03:02 ghost

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

lianxiaonm avatar Feb 25 '19 03:02 lianxiaonm

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

ZQ-jhon avatar Feb 27 '19 01:02 ZQ-jhon

总结方法就是以下几种方式:1. es6 2. reduce 3. 递归 4. toString

dengnan123 avatar Feb 27 '19 05:02 dengnan123

[...new Set(arr.toString().split(",").sort((a,b)=>{ return a-b}).map(Number))]

this is good

shizhenbin avatar Feb 28 '19 02:02 shizhenbin

arr.toString().split(",").sort((a,b)=>{ return a-b})

  1. split()方法是把字符串分割成字符数组,所以最后的排序是根据字符串的编码来排序,输出的也是字符串数组
  2. 这个方法也没有去重

set方法去重,flat方法扁平化,最后把对象转化成数组:

var arry =[1,25,15,[1,2,15,5],15,25,35,1];
var set =new Set(arry.flat(Infinity).sort((a,b)=>(a-b)));
var arr= [...set];
:
console.log(arr)// [1, 2, 5, 15, 25, 35]

参考https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/0014345007434430758e3ac6e1b44b1865178e7aff9082e000/

juwuyu avatar Feb 28 '19 06:02 juwuyu

[...new Set(arr.toString().split(',').sort(function(a,b){return a-b}).map(Number))]

thinkfish avatar Mar 04 '19 09:03 thinkfish

image

Frank-zf avatar Mar 04 '19 09:03 Frank-zf

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

1、.toString().split(',') 扁平化数据; 2、sort() 排序数据; 3、map(Number) 转数字; 4、Array.from(new Set()) 去重;

twoyoung6 avatar Mar 06 '19 06:03 twoyoung6

为什么没有人提 利用 apply 做数组降维 呢?

简单实现,不考虑 depth=Infinity 的情况

const flat = function(ary, depth) {
  let flatedAry = ary

  while(depth > 0) {
     flatedAry = [].concat.apply([], flatedAry)

     depth--
  }
  
  return flatedAry
}

再结合 Set 去重、sort 排序。 美滋滋呢~

另外, toString 的降维方式并不认同,原因是不严谨。

inJs avatar Mar 07 '19 07:03 inJs

[...arr.join().split(',')].sort(a,b) join() 数组转为字符串 split 字符串 转为数组 [...]去重 我个人觉得这个是最简单的

zhoufanglu avatar Mar 07 '19 09:03 zhoufanglu

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

faber-pan avatar Mar 11 '19 03:03 faber-pan

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

这里的 sort 里面的排序函数可以省略,直接使用 sort, 默认就是升序排列 Array.from(new Set(arr.flat(Infinity))).sort()

jjeejj avatar Mar 11 '19 06:03 jjeejj

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

const flat = (array) => [].concat(...array.map(i => Array.isArray(i) ? flat(i) : [i]));

const unique = (array) => [...new Set(array)];

const sort = (array) => array.sort((a, b) => a - b);

const compose = (...fns) => value => [...fns].reduceRight((prev, fn) => prev = fn(prev), value);

compose(sort, unique, flat)(arr);

BaconZhang avatar Mar 11 '19 07:03 BaconZhang

@BaconZhang 为啥不用 reduceRight?因为我觉得 reduceRight 比 reduce 更符合语义

ghost avatar Mar 11 '19 08:03 ghost

@liuliangsir 感谢指正,这里使用reduceRight比reverse加reduce更简洁

BaconZhang avatar Mar 11 '19 10:03 BaconZhang

@inJs apply 作用是用来降维?apply 之所以能够用来降维,是因为你借用 concat 函数吧 @BaconZhang 其实我觉得代码还是有点问题,compose(sort, unique, flat)(arr); 这种写法不太符合 pipe 理念,而且 (prev, fn) => prev = fn(prev) 这里有点问题,不需要把 fn(prev) 重新赋给 prev,可以参考 reduce 或者 reduceRight 的实现

这是我实现的 compose

function compose(...funcs) {
    return function (...args) {
        return funcs.reduceRight((prev, func) => Array.isArray(prev) ? func(...prev) : func(prev), args);
    };
}

ghost avatar Mar 12 '19 07:03 ghost

@liuliangsir compose 和 pipe 是两种思路。pipe(flow)是从前到后,compose是从后到前。

fingerpan avatar Mar 12 '19 08:03 fingerpan

var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
arr.toString().split(",").filter((item,index,arrs)=>(arrs.indexOf(item) === index)).sort((a,b)=>a-b);

KaiOrange avatar Mar 14 '19 02:03 KaiOrange

@liuliangsir 相反。 concat 可以被替换, apply 是必须的。 这个方法的缺点是有点绕,不好理解。但是兼容性好。

inJs avatar Mar 17 '19 05:03 inJs

const flat = (arr) => { return [...new Set(arr.reduce((prev, curr)=>{ return prev.concat(Array.isArray(curr) ? flat(curr) : curr) }, []))].sort((a,b)=>{return a-b}) }

LinSky avatar Mar 28 '19 08:03 LinSky

这样也是可以的:

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

Jingce-lu avatar Mar 31 '19 12:03 Jingce-lu

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

flat 参数,来判定需要去重的层数。

huangd-d avatar Apr 01 '19 02:04 huangd-d

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

function flatArr(arr, hash = {}) {
  var newArr = [];
  for (var i = 0, len = arr.length; i < len; i++) {
    if (arr[i].constructor === Array) {
      newArr.push(...flatArr(arr[i], hash));
    } else {
      if (!hash[arr[i]]) {
        newArr.push(arr[i]);
        hash[arr[i]] = 1;
      } 
    }
  }
  newArr.sort((a, b) => a - b);
  return newArr;
}


console.log(flatArr(arr));

peanutYu avatar Apr 08 '19 07:04 peanutYu

  var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
  var resArr = [];
  function dealArr(arr) {
    for (var i = 0; i < arr.length; i++) {
      var item = arr[i];
      if (Array.isArray(item)){
        dealArr(item);
      }else{
        if (resArr.indexOf(item) === -1){
          resArr[resArr.length] = item;
        }
      }
    }
  }
  
  dealArr(arr);
  
  for (var i = 0; i < resArr.length - 1; i++) {
    for (var j = i + 1; j < resArr.length; j++) {
      if (resArr[i] > resArr[j]){
        var key = resArr[i];
        resArr[i] = resArr[j];
        resArr[j] = key;
      }
    }
  }

  console.log(resArr);

Tsingwu avatar Apr 15 '19 08:04 Tsingwu

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

cliYao avatar Apr 17 '19 04:04 cliYao

arr.toString().split(",").sort((a,b)=>{ return a-b}) 这个想法可以

rwjCxgsy avatar Apr 19 '19 08:04 rwjCxgsy

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

qiuguixin avatar Apr 20 '19 14:04 qiuguixin

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

qiuguixin avatar Apr 20 '19 14:04 qiuguixin

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

chaijinsong avatar Apr 26 '19 00:04 chaijinsong

arr.toString().split(",").sort((a,b)=>{ return a-b})

这种会丢失原来的数据类型吧

fengyun2 avatar Apr 26 '19 00:04 fengyun2

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

lentoo avatar May 07 '19 01:05 lentoo

function arrayFlat(list = []) {
  return [...new Set(function (arr) {     //去重
    const newArr = Array.prototype.concat.apply([], arr)  //扁平化
    return newArr.some(Array.isArray) ? arguments.callee(newArr) : newArr;    //递归
  }(list))]
  .sort((a, b) =>a - b)  //排序
    
  

Forx-Js avatar May 07 '19 06:05 Forx-Js

    const arr = [[1, 3, 13, 1, 14], [2, 3, 4, 5], [6, 6, 7, 8, [10, 11, 21, [14]]]];

    function flatArr(arr, nodelist = []) {
      return arr.reduce((total, item) => {
        if (Array.isArray(item)) {
          flatArr(item, total);
        } else {
          total.push(item);
        }
        return total;
      }, nodelist)
    }


    const newArr = [...new Set(flatArr(arr))].sort((a, b) => a - b);

toringo avatar May 09 '19 03:05 toringo

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

zxl-lxz avatar May 09 '19 06:05 zxl-lxz

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

zz026 avatar May 09 '19 06:05 zz026

var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
var map = {};
var res = []
function depth (arr) {
	arr.forEach(item => {
		if (item instanceof Array) {
			depth(item)
		} else {
			map[item] = item
		}
	})
}
depth(arr)
for (let key in map) {
	res.push(parseInt(key))
}
res = res.sort((a, b) => a - b)
console.log(res)
//  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

5SSS avatar May 10 '19 03:05 5SSS

var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
var map = {};
var res = []
function depth (arr) {
	arr.forEach(item => {
		if (item instanceof Array) {
			depth(item)
		} else {
			map[item] = item
		}
	})
}
depth(arr)
for (let key in map) {
	res.push(parseInt(key))
}
res = res.sort((a, b) => a - b)
console.log(res)
//  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

感觉既然是算法题,这个应该是正解才对,我写出来的几乎跟你一样,而且我还在考虑sort是否也要手动的实现。 image

liujuntao123 avatar May 13 '19 11:05 liujuntao123

const flatten = arr => arr.reduce((acc, item) =>
    acc.concat(Array.isArray(item) ? flatten(item) : item), [])
const sw = arr => Array.from(new Set(flatten(arr))).sort((a, b) => a - b)
const arr = [[1,21],3,[40,5,[6,[7,8,[90,10]]]]]
console.log(sw(flat))
//  [1, 3, 5, 6, 7, 8, 10, 21, 40, 90]

BiYuqi avatar May 16 '19 15:05 BiYuqi

[...new Set(JSON.parse(`[${arr}]`).sort((a, b) => a - b))]

lhyt avatar May 16 '19 17:05 lhyt

如果重复的数都是连着的

JSON.parse( `[${`${arr}`.replace(/\b(\d+),\1/g, '$1')}]`).sort((a, b) => a - b)

lhyt avatar May 16 '19 17:05 lhyt

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

目测是用来指定要扁平化数组的层数

nailfar avatar May 17 '19 01:05 nailfar

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

flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。 参数是 要提取嵌套数组的结构深度,默认值为 1。

zz026 avatar May 17 '19 01:05 zz026

这个题面试的时候真的遇到了,用递归写了。

fireairforce avatar May 17 '19 06:05 fireairforce

考虑到元素可能不止数字,排序时候稍微改下

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

francecil avatar May 20 '19 02:05 francecil

var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]; var obj = {}; function deepClone(arr) { var attr = []; arr.forEach(function (v) { if (v.constructor === Array) { attr = attr.concat(deepClone(v)); } else { if (obj[v] === undefined) { obj[v] = v; attr.push(v); } } }); return attr; }

	console.log(deepClone(arr).sort(function (a, b) {
		return a - b;
	}))

liuchao2019 avatar May 25 '19 09:05 liuchao2019

    let arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
    let tempArray = arr.flat(); // 保存每次flat后的数组
    while(checkArrayItemHasArray(tempArray)) {
        tempArray = tempArray.flat();
    }
    tempArray = Array.from(new Set([...tempArray]));    // 去重
    tempArray = tempArray.sort((a, b) => a - b);        // 排序
    console.log(tempArray);

    // 判断数组项是否有数组类型
    function checkArrayItemHasArray(arr) {
        let result = false;
        for(let i = 0; i < arr.length; i++) {
            if (Array.isArray(arr[i])) {
                result = true;
                break;
            }
        }
        return result;
    }

liyixun avatar Jun 01 '19 03:06 liyixun

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


function flattern(arg){
    if(!Array.isArray(arg)) return false;
    const arr = arg.reduce((prev, next)=>{
        return prev.concat(Array.isArray(next) ? flattern(next) : next)
    }, [])

    return arr;
}

function unique(arg){
    return Array.from(new Set(arg))
}

function sortArr(arg) {
    const arr = arg.sort((a, b) => {
        return a-b;
    })
    return arr
}

sortArr(unique(flattern(arr)));

第一印象写出来的,原生方法 arr.flat(arg) 参数表示要展开的层级,默认也是全部展开 Infinity 全部展开。
改进地方, 参考前面的答案可以把方法挂载到原型 Array.prototype 上,实现链式调用 

jarbinup avatar Jun 17 '19 02:06 jarbinup

var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
var map = {};
var res = []
function depth (arr) {
	arr.forEach(item => {
		if (item instanceof Array) {
			depth(item)
		} else {
			map[item] = item
		}
	})
}
depth(arr)
for (let key in map) {
	res.push(parseInt(key))
}
res = res.sort((a, b) => a - b)
console.log(res)
//  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

感觉既然是算法题,这个应该是正解才对,我写出来的几乎跟你一样,而且我还在考虑sort是否也要手动的实现。 image

用了递归扁平,hash去重,冒泡排序,打开讨论区大吃一惊

Alvin1992 avatar Jul 08 '19 03:07 Alvin1992

var arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]; var res = []; var obj = {}; //扁平时去重 function flattenDeep(arr){ var target; var i = 0; for(;i < arr.length;i++){ target = arr[i]; if(Array.isArray(target)){ flattenDeep(target); }else{ //用对象来过滤重复的数据(空间换时间) if(!obj[target]){ obj[target] = target; res.push(target); } } } } flattenDeep(arr); console.log(res.sort(function(a,b){return a - b}));

yondYS avatar Jul 09 '19 01:07 yondYS

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

Bryce-Lin avatar Jul 09 '19 01:07 Bryce-Lin

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

const arrHandel = arr => [...new Set(arr.flat(Infinity))].sort((a, b) => a - b); console.log(arrHandel(arr));`

MinosIE avatar Jul 09 '19 04:07 MinosIE

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

fitbye avatar Jul 09 '19 08:07 fitbye

// 扁平化数组方法

function formatArr(arr) {
    return arr.reduce((result, item) => {
        return result.concat(item instanceof Array ? formatArr(item) : item)
    }, [])
}

// 数组去重

function noRepeat(arr) {
    var obj = {}
    var newArr= []
    arr.forEach((item, key) => {
        if( !obj[item]){
            newArr.push(item);
            obj[item] = true
        }
    })
    return newArr;
}

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

// 将相关方法统一
function unionArr(arr){
    var arr1 = formatArr(arr);
    var arr2 = noRepeat(arr1);

    arr2.sort((a, b)=>{
        return a - b
    })

    return arr2;

}
console.log(unionArr(arr))

lijiayi01 avatar Jul 09 '19 08:07 lijiayi01

[... new Set(arr.toString()。split(','))]。sort((x,y)=> x - y) 这样变成字符串了哈,加了一步 [...new Set(arr.toString().split(','))].map(val => Math.floor(val)).sort((x, y) => x - y)

zz026 avatar Jul 09 '19 09:07 zz026

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

1213204205 avatar Jul 09 '19 09:07 1213204205

前面的答案都是直接来这些高级方法,其实我是面试官,可能更愿意看到: sort,你能直接写个快排 扁平化,知道使用递归 去重,知道set结构并且自己实现一个set

最后,用函数式把这些串起来 这才perfect呀

NathanHan1 avatar Jul 09 '19 09:07 NathanHan1

// 实现:
const flat = (data) => data.reduce((acc, val) => Array.isArray(val) ? acc.concat(flat(val)) : acc.concat(val), [])
const unique = data => data.reduce((acc, val) => acc.indexOf(val) > -1 ? acc : acc.concat(val), [])
const sort = (data, order) => data.sort((a, b) => order === 'desc' ? b - a : a - b)
const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args)))
const bindRight = (fn, thisObj, ...values) => (...args) => (len = fn.length - values.length, fn.apply(thisObj, args.slice(0, len > 0 ? len : 0).concat(values.reverse())))
// 数据:
const arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
// 验证:正序
console.log(compose(sort, unique, flat)(arr))
// 输出:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
// 验证:倒序
console.log(compose(bindRight(sort, null, 'desc'), unique, flat)(arr))
// 输出:
[14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

savoygu avatar Jul 09 '19 10:07 savoygu

一种方法:[...new Set(arr.toString().split(','))].sort((a, b)=>{return a-b}).map(Number)
还有:[...new Set(arr.flat(Infinity))].sort((a,b)=>{return a- b})

Linnnsyuebaba avatar Jul 09 '19 13:07 Linnnsyuebaba

捕获

Jimi1126 avatar Jul 09 '19 16:07 Jimi1126

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

tongchuan avatar Jul 10 '19 01:07 tongchuan

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

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

[... new Set(arr.toString().split(",").sort((a,b)=>{ return a-b}).map(Number))]

gezi666 avatar Jul 10 '19 01:07 gezi666

// 递归方式 数组扁平化

var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
function flat(arr) {
	let _arr = Array.from(arr);
	let res = [];
	_arr.map(el => {
		if (el instanceof Array) {
			res = res.concat(flat(el))
		} else {
			res.push(el)
		}
	})
	return res
}

答案为: [...new Set(flat(arr))].sort((a,b)=>{return a - b})

udbbbn avatar Jul 10 '19 02:07 udbbbn

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

这个目前低版本浏览器是不支持的 需要es7 babel支持

YOMXXX avatar Jul 10 '19 02:07 YOMXXX

现在项目基本都会用babel-polyfill去做转码的

------------------ 原始邮件 ------------------ 发件人: "Angular"[email protected]; 发送时间: 2019年7月10日(星期三) 上午10:30 收件人: "Advanced-Frontend/Daily-Interview-Question"[email protected]; 抄送: "每一天"[email protected]; "Comment"[email protected]; 主题: Re: [Advanced-Frontend/Daily-Interview-Question] 第 11 题:将数组扁平化并去除其中重复数据,最终得到一个升序且不重复的数组 (#8)

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

这个目前低版本浏览器是不支持的 需要es7 babel支持

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

gezi666 avatar Jul 10 '19 02:07 gezi666

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

imccode avatar Jul 10 '19 04:07 imccode

发一个不是很成熟的解决方法 :

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

arixse avatar Jul 10 '19 08:07 arixse

@zpzxgcr 测试结果,如果将Array1.flat(Infinity)替换为:Array2.toString().split(',') #能省300多ms

LoopFlying avatar Jul 10 '19 10:07 LoopFlying

arr.flat(Infinity)
  .sort((a, b) => a - b)
  .filter((item, index, arr) => index == 0 || arr[index-1] != item)

sqrtqiezi avatar Jul 10 '19 10:07 sqrtqiezi