首先了解一下什么是数组扁平化?
将一个嵌套多层的数组Array(嵌套可以是任何层数)转换为只有一层的数组。
数组去重
先总结数组的方法:pop、push、shift、unshift、sort、splice、slice、revere、concat
join、indexOf、map、forEach、includes、find、filter、reduce
shift:shift()
方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度
unshift:unshift()
方法将一个或多个元素添加到数组的开头,并返回该数组的新长度。
slice:slice()
方法返回一个新的数组对象,这一对象是一个由 begin
和 end
决定的原数组的浅拷贝(包括 begin
,不包括end
)。原始数组不会被改变。
splice:splice()
方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。注意splice会改变原数组
some:some()
方法测试数组中是不是至少有 1 个元素通过了被提供的函数测试。它返回的是一个 Boolean 类型的值
reverse:reverse()
方法将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。该方法会改变原数组。
sort:也会改变原数组
from :Array.from()
方法对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。 filter不会改变原数组,reduce、foeEach、map、join、concat、slice、findIndex都不会改变原数组。
console.log(Array.from('foo')); // Expected output: Array ["f", "o", "o"] console.log(Array.from([1, 2, 3], x => x + x)); // Expected output: Array [2, 4, 6]
filter:filter()
方法创建给定数组一部分的浅拷贝,其包含通过所提供函数实现的测试的所有元素
①新建一个数组用来存放结果,遍历原数组,每次从其中取出一个元素和结果数组进行比较,如果原数组中元素没有在结果数组中出现过,就将这个元素保存到结果数组中
很显然复杂度是O(n^2)
代码优化一下:
indexOf()
方法返回在数组(字符串同理)中可以找到给定元素的第一个索引,如果不存在,则返回 -1。
function unique1(arr){ var uniqueArr = []; for(var i=0; i<arr.length; i++){
在结果数组里面找不到就加入 if(uniqueArr.indexOf(arr[i]) == -1){ uniqueArr.push(arr[i]); } } return uniqueArr; }
②方法二:利用对象字面量的key和value关联性,新建一个对象和数组,遍历传入数组时,
判断值是否为js对象的键,不是的话给对象新增该键并放入新数组。
特点:速度快,但是需要占用内存相对大一点。
注意:判断是否为js对象键时,会自动对传入的键执行“toString()”,不同的键可能会被误认为一样。
function unique2_origin(arr){ var obj = {}; var uniqueArr = []; // 结果数组 var type; // 记录元素的数据类型 for(var i=0; i<arr.length; i++){ type = typeof arr[i]; if( !obj[arr[i]]){ obj[arr[i]] = [type]; uniqueArr.push(arr[i]); }else if(obj[arr[i]].indexOf(type) < 0){ obj[arr[i]].push(type); uniqueArr.push(arr[i]); } } return uniqueArr; } function unique2(arr){ var uniqueArr = []; var obj = {}; for(var i=0; i<arr.length; i++){ var key = typeof(arr[i]) + arr[i]; if( obj[key] !== 1){ uniqueArr.push(arr[i]); obj[key] = 1; } } return uniqueArr; } // 测试 var arr1 = [1, 2, '13', 1, '5', '9', 1, 12, 12, 2, '5', 13, 'e', 'e', 'a', 'a', 'b', 'd',13]; console.log("原数组:") console.log(arr1); console.log("去重后的数组应该是:") console.log([1, 2, '13', '5', '9', 12, 13, 'e', 'a', 'b', 'd']); console.log("方法二:") console.log(unique2_origin(arr1)); console.log(unique2(arr1));
③set方法
let arr = [12,1,12,3,1,88,66,9,66]; function unique(ary) { let s = new Set(ary); // Array.from : 将set数据结构转成真正的数组; return Array.from(s) } unique(arr);
④includes
let arr = [12,1,12,3,1,88,66,9,66]; function unique(ary) { let newAry = []; let len = ary.length; for(let i=0;i<len;i++){ let cur = ary[i]; if(!newAry.includes(cur)){ newAry.push(cur); } } return newAry; } console.log(unique(arr));
⑤hasOwnProperty : 检测属性名是否是对象的一个私有属性;返回一个布尔值
let arr = [12,1,12,3,1,88,66,9,66]; function unique(ary) { let obj = {}; return ary.filter(function (item,index,a) { // item : 数组每一个成员 // index: 成员对应的索引 // a : 整个数组 // hasOwnProperty来校验的该属性是否出现过; return obj.hasOwnProperty(typeof item+item)?false:obj[typeof item+item]=true; if(obj.hasOwnProperty(typeof item+item)){ return false }else{ obj[typeof item+item]=true; return true; } }) } console.log(unique(arr))
⑥filter+indexOf
let arr = [12,1,12,3,1,88,66,9,66]; function unique(ary) { return ary.filter(function (item,index,a) { return ary.indexOf(item)===index; }) } console.log(unique(arr));
⑦splice+双重循环判断进行删除
let arr = [12,1,12,3,1,88,66,9,66]; function unique(ary) { for(let i=0;i<ary.length;i++){ for(j=i+1;j<ary.length;j++){ if(ary[i]===ary[j]){ ary.splice(j,1); j--; } } } return ary; } unique(arr);
⑧递归
let arr = [12,1,12,3,1,88,66,9,66]; function unique(ary) { let len= ary.length; ary = ary.sort(function (a,b) { return a-b; }); function loop(index) { if(index>=1){ if(ary[index]===ary[index-1]){ ary.splice(index,1); } loop(index-1) } } loop(len-1); return ary; } console.log(unique(arr));
⑨map数据结构存值特性
let arr = [12,1,12,3,1,88,66,9,66]; function unique(ary) { let newAry =[]; let map = new Map(); for(let i=0;i<ary.length;i++){ if(!map.has(ary[i])){ map.set(ary[i],true); newAry.push(ary[i]); } } } unique(arr);
⑩reduce
let arr = [12,1,12,3,1,88,66,9,66]; function unique(ary) { // reduce : 第一个是函数,第二个参数会传给第一次回调的prev; return ary.reduce((prev,next)=>{ // 该函数返回值是下一次执行的prev; return prev.includes(next)?prev:[...prev,next]; },[]) } console.log(unique(arr));
set实例对象的方法
add(value)
:添加某个值,返回Set
结构本身(可以链式调用)。delete(value)
:删除某个值,删除成功返回true
,否则返回false
。has(value)
:返回一个布尔值,表示该值是否为Set
的成员。clear()
:清除所有成员,没有返回值。
Array.from
方法可以将 Set
结构转为数组。
WeakSet
WeakSet
结构与 Set
类似,也是不重复的值的集合。
只不过成员都是弱引用,可以被垃圾回收机制回收,可以用来保存 DOM 节点,不容易造成内存泄漏。
WeakSet
没有 size
属性
map转为数组
let arr = []
arr=[...map]
WeakMap
- 只接受对象作为键名(
null
除外),不接受其他类型的值作为键名 - 键名是弱引用,键值可以是任意的,键名所指向的对象可以被垃圾回收,此时键名是无效的
- 不能遍历,方法有
get
、set
、has
、delete
上述去重方法大部分优点都是可以区分“1‘和1,缺点是对象不可以去重
只有对象键值对方法 优点是NAN可以重,正则可以去冲,缺点是不可以区分“1‘和1,对象也不能去重
标签:arr,12,扁平化,66,ary,优缺点,let,数组,最值 From: https://www.cnblogs.com/alwaysrun/p/17179455.html