javascript数组方法 == js数组去重 == js中数组排序(冒泡、快速、插入)== js中数组扁平化处理
javascript数组方法 == js数组去重
参看如下链接:
1.https://www.cnblogs.com/cauliflower/p/11267809.html
2.https://www.cnblogs.com/zyfeng/p/10541133.html
===========================================================
js数组去重
情境:
将数组var arr = [1,1,‘true’,‘true’,true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,‘NaN’, 0, 0, ‘a’, ‘a’,{},{}]
中重复的值过滤掉
1、 ES6-set
使用ES6中的set是最简单的去重方法
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,
undefined, null,null, NaN,NaN,'NaN', 0, 0, 'a', 'a',{ },{ }];
function arr_unique1(arr){
return [...new Set(arr)];
//或者
//return Array.from(new Set(arr));
}
arr_unique1(arr);
/* (13)[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]*/
该方法可以说是最完美的方法,就是需要环境支持ES6
2、利用Map数据结构去重
创建一个空Map数据结构,遍历需要去重的数组,把数组的每一个元素作为key存到Map中。由于Map中不会出现相同的key值,所以最终得到的就是去重后的结果。
function arr_unique2(arr) {
let map = new Map();
let array = new Array(); // 数组用于返回结果
for (let i = 0; i < arr.length; i++) {
if(map .has(arr[i])) { // 如果有该key值
map .set(arr[i], true);
} else {
map .set(arr[i], false); // 如果没有该key值
array .push(arr[i]);
}
}
return array ;
}
console.log(arr_unique2(arr));
/*(13) [1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, "NaN", 0, "a", {…}, undefined]*/
3、 利用递归去重
function arr_unique3(arr) {
var array= arr;
var len = array.length;
array.sort(function(a,b){ //排序后更加方便去重
return a - b;
})
function loop(index){
if(index >= 1){
if(array[index] === array[index-1]){
array.splice(index,1);
}
loop(index - 1); //递归loop,然后数组去重
}
}
loop(len-1);
return array;
}
console.log(arr_unique3(arr));
/*(14) [1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, "NaN", 0, "a", {…}, undefined]*/
4、 forEach + indexOf
function arr_unique4(arr){
var res = [];
arr.forEach((val,index)=>{
if( res.indexOf(val) === -1 ){
res.push(val);
}
});
return res;
}
console.log(arr_unique4(arr));
/* (14) [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN", 0, "a", {…}, {…}]*/
该方法的不足之处在于无法对NaN进行过滤,原因是var a = [1, NaN , 2]; a.indexOf(NaN) === -1;,改善的方法是使用includes方法
5、 filter+indexOf
function arr_unique5(arr){
return arr.filter((val,index,item)=>{
return item.indexOf(val) === index;
});
}
arr_unique5(arr);
/*(12) [1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {…}, {…}]*/
美中不足的地方在于漏掉了NaN,原因同方法四
6、 forEach + includes
function arr_unique6(arr){
var res = [];
arr.forEach((val)=>{
if( ! res.includes(val) ){
res.push(val);
}
});
return res;
}
arr_unique6(arr);
/* (13) [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]*/
该方法也算是比较完美,没有什么遗漏的地方
7、 reduce + includes
function arr_unique7(arr){
return arr.reduce( (prev, cur )=>{
if( ! prev.includes(cur) ){
prev.push(cur);
}
return prev;
} ,[]);
}
arr_unique7(arr);
/*(13)[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]*/
8、 嵌套循环+splice
function arr_unique8(arr){
for(var i = 0 ; i < arr.length; i++){
for( var j = i + 1; j < arr.length; j++){
if( arr[i] === arr[j] ){
arr.splice(j,1);
}
}
}
return arr;
}
arr_unique8(arr);
/*(14) [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN" , 0, "a", {…}, {…}]*/
这是最麻烦的方法,效率十分低下,每一个循环都会去动态获取数组的length。且该方法无法过滤掉NaN,因为NaN === NaN的结果为false。
9、 hash+hasOwnProperty+JSON.stringify(终级版)
function arr_unique9(arr){
var hash = { };
return arr.filter( (val)=>{
return hash.hasOwnProperty( typeof val + JSON.stringify(val) )
? false : hash[typeof val + JSON.stringify(val)] = true ;
});
}
arr_unique9(arr);
/*(12) [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}]*/
这种方法是终极版的,因为它可以进行数组中的对象元素的去重!前面的几种方法是不可以进行对象去重的。不过话说回来,JS中的对象是本身就是一个地址的引用,比如 {} == {} ;//false,两者是两个不同的对象,这里我将其进行JSON.stringify进行简化。
经亲测,使用ES6的Set和Map效率最高,reduce()和sort()效率还可以,双层循环效率最低。
数组去重大全,你,get到了吗~
===========================================================
js中数组排序(冒泡、快速、插入)
1.冒泡排序法
将数组中的相邻两个元素进行比较,将比较大(较小)的数通过两两比较移动到数组末尾(开始),执行一遍内层循环,确定一个最大(最小)的数,外层循环从数组末尾(开始)遍历到开始(末尾)
function MaoPaoSort(arr){
for(var i = 0;i<arr.length-1;i++) {
for(var j = 0;j<arr.length-i-1;j++){
if(arr[j]>arr[j+1]){
//把大的数字放到后面
var str = arr[j];
arr[j] = arr[j+1];
arr[j+1] = str;
}
}
}
}
var arr = [3,5,1,2,7,8,4,5,3,4];
//console.log(arr);[3,5,1,2,7,8,4,5,3,4];
MaoPaoSort(arr);
//console.log(arr);[1, 2, 3, 3, 4, 4, 5, 5, 7, 8]
2. 插入排序法(插队排序)
将要排序的数组分成两部分,每次从后面的部分取出索引最小的元素插入到前一部分的适当位置
从第一个元素开始,该元素可以认为已经被排序;
取出下一个元素,在已经排序的元素序列中从后向前扫描;
如果该元素(已排序)大于新元素,将该元素移到下一位置;
重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
将新元素插入到该位置后;
重复步骤2~5。
function InsertSort(arr) {
let len = arr.length;
let preIndex, current;
for (let i = 1; i < len; i++) {preIndex = i - 1;
current = arr[i];
while (preIndex >= 0 && current < arr[preIndex]) {
arr[preIndex + 1] = arr[preIndex];
preIndex--;
}
arr[preIndex + 1] = current;
}
return arr;
}var arr = [3,5,7,1,4,56,12,78,25,0,9,8,42,37];
InsertSort(arr);
3.快速排序
在看完上面的东西之后,不知道大家有没有发现在实际的工作中如果数据量过大,数组比较复杂,通过两次遍历,同时会带来性能上的问题,不用慌,我们还可以用快速排序的方法进行解决,快速排序对冒泡排序的一种改进
实现思路是,将一个数组的排序问题看成是两个小数组的排序问题,以一个数为基准(中间的数),比基准小的放到左边,比基准大的放到右边,而每个小的数组又可以继续看成更小的两个数组,一直递归下去,直到数组长度大小最大为2。
function quickSort(arr){
//如果数组长度小于1,没必要排序,直接返回
if(arr.length<=1) return arr;
//pivot 基准索引,长度的一半
let pivotIndex = Math.floor(arr.length/2);//奇数项向下取整
//找到基准,把基准项从原数组删除
let pivot = arr.splice(pivotIndex,1)[0];
//定义左右数组
let left = [];
let right = [];
//把比基准小的放left,大的放right
arr.forEach(element => {
if(element<pivot){
left.push(element)
}else{
right.push(element)
}
});
return quickSort(left).concat([pivot],quickSort(right))
}
var arr=[4,56,3,67,44,5,66];
console.log(quickSort(arr));//[3, 4, 5, 44, 56, 66, 67]
===========================================================
js中数组扁平化处理
经典面试题,项目中用js数组操作的地方很多,js数组扁平化是其中一种
什么是数组扁平化?
数组扁平化就是将一个多维数组转换为一个一维数组
实现基本方式
1、对数组的每一项进行遍历。
2、判断该项是否是数组。
3、如果该项不是数组则将其直接放进新数组。
4、是数组则回到1,继续迭代。
5、当数组遍历完成,返回这个新数组。
1.常规方式 递归处理
Array.prototype.flatten = function () {
var resultArr = [];
var len = this.length;
for (var i = 0; i < len; i ++) {
if (Array.isArray(this[i])) {
resultArr = resultArr.concat(this[i].flatten());
} else {
resultArr.push(this[i]);
}
}
return resultArr;
}
var arr=[1,2,3,[4,5,'hello',['world',9,666]]]
console.log(arr.flatten())//[1, 2, 3, 4, 5, "hello", "world", 9, 666]
2.使用reduce方法
Array.prototype.flatten = function () {
return this.reduce(function (prev, cur, curIndex, arr) {
return Array.isArray(cur) ? prev.concat(cur.flatten())
: prev.concat(cur);
}, []);
}
Array.prototype.flatten = function () {
return this.reduce(function (prev, cur, curIndex, arr) {
return Array.isArray(cur) ? prev.concat(cur.flatten())
: prev.concat(cur);
}, []);
}
3. yield*的用法,天才级别的扁平化方式
function* iterTree(tree){
if(Array.isArray(tree)){
for(let i = 0 ;i<tree.length;i++){
yield* iterTree(tree[i]);
}
}else{
yield tree;
}
}
let arr1 = [1, 2, ['a', 'b', ['中', '文', [1, 2, 3, [11, 21, 31]]]], 3];
let list=[]
for (const x of iterTree(arr1)) {
list.push(x)
}
console.log(list);//[1, 2, "a", "b", "中", "文", 1, 2, 3, 11, 21, 31, 3]
4. es6中的flat函数也可以实现数组的扁平化
let arr1 = [1,2,['a','b',['中','文',[1,2,3,[11,21,31]]]],3];
console.log( arr1.flat( Infinity ) );
5.扩展运算符
//ES6 增加了扩展运算符,用于取出参数对象的所有可遍历属性,拷贝到当前对象之中:
var arr = [1, [2, [3, 4]]];
console.log([].concat(...arr)); // [1, 2, [3, 4]]
//我们用这种方法只可以扁平一层,但是顺着这个方法一直思考,我们可以写出这样的方法:
// 改进
var arr = [1, [2, [3, 4]]];
function flatten(arr) {
while (arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr);
}
return arr;
}
console.log(flatten(arr))
还没有评论,来说两句吧...