javascript数组方法 == js数组去重 == js中数组排序(冒泡、快速、插入)== js中数组扁平化处理

忘是亡心i 2022-12-26 11:19 254阅读 0赞

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是最简单的去重方法
  1. var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,
  2. undefined, null,null, NaN,NaN,'NaN', 0, 0, 'a', 'a',{ },{ }];
  3. function arr_unique1(arr){
  4. return [...new Set(arr)];
  5. //或者
  6. //return Array.from(new Set(arr));
  7. }
  8. arr_unique1(arr);
  9. /* (13)[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]*/
该方法可以说是最完美的方法,就是需要环境支持ES6

2、利用Map数据结构去重

创建一个空Map数据结构,遍历需要去重的数组,把数组的每一个元素作为key存到Map中。由于Map中不会出现相同的key值,所以最终得到的就是去重后的结果。
  1. function arr_unique2(arr) {
  2. let map = new Map();
  3. let array = new Array(); // 数组用于返回结果
  4. for (let i = 0; i < arr.length; i++) {
  5. if(map .has(arr[i])) { // 如果有该key值
  6. map .set(arr[i], true);
  7. } else {
  8. map .set(arr[i], false); // 如果没有该key值
  9. array .push(arr[i]);
  10. }
  11. }
  12. return array ;
  13. }
  14. console.log(arr_unique2(arr));
  15. /*(13) [1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, "NaN", 0, "a", {…}, undefined]*/

3、 利用递归去重

  1. function arr_unique3(arr) {
  2. var array= arr;
  3. var len = array.length;
  4. array.sort(function(a,b){ //排序后更加方便去重
  5. return a - b;
  6. })
  7. function loop(index){
  8. if(index >= 1){
  9. if(array[index] === array[index-1]){
  10. array.splice(index,1);
  11. }
  12. loop(index - 1); //递归loop,然后数组去重
  13. }
  14. }
  15. loop(len-1);
  16. return array;
  17. }
  18. console.log(arr_unique3(arr));
  19. /*(14) [1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, "NaN", 0, "a", {…}, undefined]*/

4、 forEach + indexOf

  1. function arr_unique4(arr){
  2. var res = [];
  3. arr.forEach((val,index)=>{
  4. if( res.indexOf(val) === -1 ){
  5. res.push(val);
  6. }
  7. });
  8. return res;
  9. }
  10. console.log(arr_unique4(arr));
  11. /* (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

  1. function arr_unique5(arr){
  2. return arr.filter((val,index,item)=>{
  3. return item.indexOf(val) === index;
  4. });
  5. }
  6. arr_unique5(arr);
  7. /*(12) [1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {…}, {…}]*/
美中不足的地方在于漏掉了NaN,原因同方法四

6、 forEach + includes

  1. function arr_unique6(arr){
  2. var res = [];
  3. arr.forEach((val)=>{
  4. if( ! res.includes(val) ){
  5. res.push(val);
  6. }
  7. });
  8. return res;
  9. }
  10. arr_unique6(arr);
  11. /* (13) [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]*/
该方法也算是比较完美,没有什么遗漏的地方

7、 reduce + includes

  1. function arr_unique7(arr){
  2. return arr.reduce( (prev, cur )=>{
  3. if( ! prev.includes(cur) ){
  4. prev.push(cur);
  5. }
  6. return prev;
  7. } ,[]);
  8. }
  9. arr_unique7(arr);
  10. /*(13)[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]*/

8、 嵌套循环+splice

  1. function arr_unique8(arr){
  2. for(var i = 0 ; i < arr.length; i++){
  3. for( var j = i + 1; j < arr.length; j++){
  4. if( arr[i] === arr[j] ){
  5. arr.splice(j,1);
  6. }
  7. }
  8. }
  9. return arr;
  10. }
  11. arr_unique8(arr);
  12. /*(14) [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN" , 0, "a", {…}, {…}]*/
这是最麻烦的方法,效率十分低下,每一个循环都会去动态获取数组的length。且该方法无法过滤掉NaN,因为NaN === NaN的结果为false。

9、 hash+hasOwnProperty+JSON.stringify(终级版)

  1. function arr_unique9(arr){
  2. var hash = { };
  3. return arr.filter( (val)=>{
  4. return hash.hasOwnProperty( typeof val + JSON.stringify(val) )
  5. ? false : hash[typeof val + JSON.stringify(val)] = true ;
  6. });
  7. }
  8. arr_unique9(arr);
  9. /*(12) [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}]*/
这种方法是终极版的,因为它可以进行数组中的对象元素的去重!前面的几种方法是不可以进行对象去重的。不过话说回来,JS中的对象是本身就是一个地址的引用,比如 {} == {} ;//false,两者是两个不同的对象,这里我将其进行JSON.stringify进行简化。
经亲测,使用ES6的Set和Map效率最高,reduce()和sort()效率还可以,双层循环效率最低。
数组去重大全,你,get到了吗~

===========================================================

js中数组排序(冒泡、快速、插入)

1.冒泡排序法

将数组中的相邻两个元素进行比较,将比较大(较小)的数通过两两比较移动到数组末尾(开始),执行一遍内层循环,确定一个最大(最小)的数,外层循环从数组末尾(开始)遍历到开始(末尾)
在这里插入图片描述

  1. function MaoPaoSort(arr){
  2. for(var i = 0;i<arr.length-1;i++) {
  3. for(var j = 0;j<arr.length-i-1;j++){
  4. if(arr[j]>arr[j+1]){
  5. //把大的数字放到后面
  6. var str = arr[j];
  7. arr[j] = arr[j+1];
  8. arr[j+1] = str;
  9. }
  10. }
  11. }
  12. }
  13. var arr = [3,5,1,2,7,8,4,5,3,4];
  14. //console.log(arr);[3,5,1,2,7,8,4,5,3,4];
  15. MaoPaoSort(arr);
  16. //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++) {

    1. preIndex = i - 1;
    2. current = arr[i];
    3. while (preIndex >= 0 && current < arr[preIndex]) {
    4. arr[preIndex + 1] = arr[preIndex];
    5. preIndex--;
    6. }
    7. 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。

  1. function quickSort(arr){
  2. //如果数组长度小于1,没必要排序,直接返回
  3. if(arr.length<=1) return arr;
  4. //pivot 基准索引,长度的一半
  5. let pivotIndex = Math.floor(arr.length/2);//奇数项向下取整
  6. //找到基准,把基准项从原数组删除
  7. let pivot = arr.splice(pivotIndex,1)[0];
  8. //定义左右数组
  9. let left = [];
  10. let right = [];
  11. //把比基准小的放left,大的放right
  12. arr.forEach(element => {
  13. if(element<pivot){
  14. left.push(element)
  15. }else{
  16. right.push(element)
  17. }
  18. });
  19. return quickSort(left).concat([pivot],quickSort(right))
  20. }
  21. var arr=[4,56,3,67,44,5,66];
  22. console.log(quickSort(arr));//[3, 4, 5, 44, 56, 66, 67]

在这里插入图片描述

===========================================================

js中数组扁平化处理

经典面试题,项目中用js数组操作的地方很多,js数组扁平化是其中一种

什么是数组扁平化?

数组扁平化就是将一个多维数组转换为一个一维数组

实现基本方式

1、对数组的每一项进行遍历。
2、判断该项是否是数组。
3、如果该项不是数组则将其直接放进新数组。
4、是数组则回到1,继续迭代。
5、当数组遍历完成,返回这个新数组。

1.常规方式 递归处理

  1. Array.prototype.flatten = function () {
  2. var resultArr = [];
  3. var len = this.length;
  4. for (var i = 0; i < len; i ++) {
  5. if (Array.isArray(this[i])) {
  6. resultArr = resultArr.concat(this[i].flatten());
  7. } else {
  8. resultArr.push(this[i]);
  9. }
  10. }
  11. return resultArr;
  12. }
  13. var arr=[1,2,3,[4,5,'hello',['world',9,666]]]
  14. console.log(arr.flatten())//[1, 2, 3, 4, 5, "hello", "world", 9, 666]

2.使用reduce方法

  1. Array.prototype.flatten = function () {
  2. return this.reduce(function (prev, cur, curIndex, arr) {
  3. return Array.isArray(cur) ? prev.concat(cur.flatten())
  4. : prev.concat(cur);
  5. }, []);
  6. }
  7. Array.prototype.flatten = function () {
  8. return this.reduce(function (prev, cur, curIndex, arr) {
  9. return Array.isArray(cur) ? prev.concat(cur.flatten())
  10. : prev.concat(cur);
  11. }, []);
  12. }

3. yield*的用法,天才级别的扁平化方式

  1. function* iterTree(tree){
  2. if(Array.isArray(tree)){
  3. for(let i = 0 ;i<tree.length;i++){
  4. yield* iterTree(tree[i]);
  5. }
  6. }else{
  7. yield tree;
  8. }
  9. }
  10.  let arr1 = [1, 2, ['a', 'b', ['中', '文', [1, 2, 3, [11, 21, 31]]]], 3];
  11. let list=[]
  12. for (const x of iterTree(arr1)) {
  13. list.push(x)
  14. }
  15. console.log(list);//[1, 2, "a", "b", "中", "文", 1, 2, 3, 11, 21, 31, 3]

4. es6中的flat函数也可以实现数组的扁平化

  1. let arr1 = [1,2,['a','b',['中','文',[1,2,3,[11,21,31]]]],3];
  2. console.log( arr1.flat( Infinity ) );

5.扩展运算符

  1. //ES6 增加了扩展运算符,用于取出参数对象的所有可遍历属性,拷贝到当前对象之中:
  2. var arr = [1, [2, [3, 4]]];
  3. console.log([].concat(...arr)); // [1, 2, [3, 4]]
  4. //我们用这种方法只可以扁平一层,但是顺着这个方法一直思考,我们可以写出这样的方法:
  5. // 改进
  6. var arr = [1, [2, [3, 4]]];
  7. function flatten(arr) {
  8. while (arr.some(item => Array.isArray(item))) {
  9. arr = [].concat(...arr);
  10. }
  11. return arr;
  12. }
  13. console.log(flatten(arr))

发表评论

表情:
评论列表 (有 0 条评论,254人围观)

还没有评论,来说两句吧...

相关阅读

    相关 js数组扁平处理

    经典面试题,项目中用js数组操作的地方很多,js数组扁平化是其中一种 什么是数组扁平化? > 数组扁平化就是将一个多维数组转换为一个一维数组 实现基本方式 1、对数

    相关 JS数组扁平

    一道笔试题,将一个嵌套数组扁平化处理。   ▍题目 > 将\[1,2,\[3,\[4,5\]\]\]转化成\[1,2,3,4,5\]。   ▍方法一:递归

    相关 js 数组扁平

    第一种 > 依次把每一项添加进新数组 > 如果为非数组,直接添加 > 如果为数组,则添加递归操作的结果 function flatten(ar