Sunny-117 / js-challenges

✨✨✨ Challenge your JavaScript programming limits step by step
https://juejin.cn/column/7244788137410560055
2.01k stars 236 forks source link

Array.prototype.flat #9

Open Sunny-117 opened 2 years ago

Sunny-117 commented 2 years ago
const arr = [1, [2, 3, [4, 5]], 1, 2, [6, 7]]
Array.prototype.flat = function (deep = 1) {
    let res = []
    deep--
    for (const p of this) {
        if (Array.isArray(p) && deep >= 0) {
            res = res.concat(p.flat(deep))
        } else {
            res.push(p)
        }
    }
    return res
}
console.log(arr.flat(1))
Nasuke commented 2 years ago
const arr = [1, [2, 3, [4, 5]], 1, 2, [6, 7]]
Array.prototype.falt = function () {
    return this.reduce((pre, cur) => {
        cur instanceof Array ? pre.push(...cur.falt()) : pre.push(cur)
        return pre
    }, [])
}
console.log(arr.falt());
truejiang commented 2 years ago
const arr = [1, 2, [3, 4, [5, 6]]] 
Array.prototype._flat = function (depth = Infinity) {
  --depth
  return this.reduce((prev, curr) => {
      if(Array.isArray(curr) && depth >= 0) {
          prev = prev.concat(curr._flat(depth))
      } else {
          prev.push(curr)
      }
      return prev
  }, [])
}

console.log(arr._flat())
console.log(arr._flat(1))
JiaChenHuang commented 1 year ago
const arr = [1, [2, [3, [4, [5, [6, [7, [8, [9], 10], 11], 12], 13], 14], 15], 16]]
Array.prototype.flat = function (deep = 1) {
    let res = []
    if (deep === 'Infinity') {
        this.forEach((item) => {
            if (Array.isArray(item)) {
                res = res.concat(item.flat());
            } else {
                res.push(item)
            }
        })
    } else {
        deep--
        this.forEach(item => {
            if (Array.isArray(item) && deep >= 0) {
                res = res.concat(item.flat(deep))
            } else {
                res.push(item)
            }
        })

        return res
    }

}
console.log('展开一层', arr.flat(1))
console.log('完全展开', arr.flat(Infinity))
Leadgq commented 1 year ago

Array.prototype._flat = function (depth = Infinity) { if (!Array.isArray(this) && this.length === 0) return; depth--; return this.reduce((prev, cur) => { if (Array.isArray(cur) && depth >= 0) { prev = [...prev, ...cur._flat(depth)] } else { prev.push(cur); } return prev }, []) }

veneno-o commented 1 year ago
Array.prototype._flat = function (deep = 1) {
    if(deep === 0) return this;
    let res = [];
    for (const item of this) {
        if (Array.isArray(item)) {
            res = res.concat(item._flat(--deep));
        } else {
            res.push(item);
        }
    }
    return res;
};
const arr = [12, 2, 4, [1, 3, [2, 34,[34,5]]]];

console.log(arr._flat(0));
console.log(arr._flat(1));
console.log(arr._flat(2));
console.log(arr._flat(Infinity));
litt1esea commented 1 year ago
const arr = [1, [2, 3, [4, 5]], 1, 2, [6, 7]]

Array.prototype._flat = function (deep = 1) {
    let res = []
    deep--
    for (const p of this) {
        if (Array.isArray(p) && deep >= 0) {
            res = res.concat(p._flat(deep))
        } else {
            res.push(p)
        }
    }
}

const val = [1, 2, [3, 4, [5, 6]]] .flat()
console.log(val);
jlx2002 commented 1 year ago

1. 递归解法

递归的思路很简单,遍历数组,如果数组内部出现数组,进行递归操作, 直到不是数组类型或者层数达到所给参数的阈值,加入到答案数组中。

/**
 * @description: 递归解决 数组扁平化flat
 * @param {*} nums
 * @param {*} deepth
 * @return {*}
 */
function flat1(nums, deepth = 1){
    // 如果是 无穷大,默认20层
    if(deepth === Infinity){
        deepth = 20;
    }
    // 校验参数
    if(deepth <= 0){
        return nums;
    }
    const result = [];
    function flats(arr, deep){
        arr.forEach(element => {
            // 控制递归条件
            if(Array.isArray(element) && deep > 0){
                flats(element, deep - 1);
            }else{
                result.push(element)
            }            
        });
    }
    flats(nums,deepth)
    return result;
}

2. 迭代解法

递归转迭代一般就比较难思考,这里我们可以引入一个队列的概念,栈也可以(但是栈的思考方式不太好想), 层数最多有deepth 层,于是,可以把每层想象成一个状态,每次检查这个状态,并更新即可。

/**
 * @description: 迭代 解决数组扁平化flat
 * @param {*} nums
 * @param {*} deepth
 * @return {*}
 */
function flat2(nums, deepth = 1){
    // 如果是 无穷大,默认20层
    if(deepth === Infinity){
        deepth = 20;
    }
    // 校验参数
    if(deepth <= 0){
        return nums;
    }
    //  用队列层数的思想代替递归
    const queue =  [...nums];
    let deep = 0;
    while(deep <= deepth){
        deep += 1;
        for(let i = 0, n = queue.length;i < n; i ++) {
            const top = queue.shift(); // 取出队头元素
            // 如果队头元素是数组
            if(Array.isArray(top) && deep <= deepth){
                // 展开后进行入队
                queue.push(...top);
            }else{
                // 如果不是array, 直接入队
                queue.push(top)
            }
        }
    }
    return queue;
}
Stream-web commented 1 year ago

const flatten = (arr) => arr.toString().split(',').map((item) => +item);

ych-chen commented 1 year ago

reduce方法

const arr2 = [0, 1, 2, [[[3, 4]]]];

function _flat(arr, depth){
    if( !Array.isArray(arr) || depth <= 0){
        return arr;
    }
    return arr.reduce((prev,cur) => {
        if(Array.isArray(cur)){
            return prev.concat(_flat(cur,depth-1));
        } else {
            return prev.concat(cur);
        }
    },[]);
}

_flat(arr2,3)
zzyyhh22lx commented 1 year ago
// Array.prototype.flat() 扁平化数组,参数代表展开的层数(默认1)
const arr = [1,2,[3,[4]]];
arr.flat(Infinity) // [1,2,3,4]

/**
 * 无副作用(不会改变原数组)
 * @param {*} depth 
 */
Array.prototype._flat = function (depth = 1) {
    return this.reduce((acc, cur) => { // 前一个值,当前值
        cur instanceof Array ? (function() { // 只能是表达式
            if(depth-- > 0) acc.push(...cur._flat(depth))
            else acc.push(cur)
        })() : acc.push(cur);
        return acc;
    }, [])
}
console.log(arr._flat(Infinity))
Tsuizen commented 1 year ago
function flatten(arr, deep) {
  while (arr.some(item => Array.isArray(item)) && deep) {
    arr = [].concat(...arr);
    deep--;
  }
  return arr;
}
sv-98-maxin commented 1 year ago

Array.prototype.myFlat = function (depth = 1) {
  const flat = arr => {
    return arr.reduce((prev, next) => {
      if (Array.isArray(next)) {
        prev.push(...next)
      } else {
        prev.push(next)
      }
      return prev
    }, [])
  }
  let res = this
  while (depth > 0) {
    res = flat(res)
    depth--
  }
  return res
}
bearki99 commented 1 year ago
Array.prototype.myFlat = function (deep = Infinity) {
  let res = [];
  deep--;
  this.forEach((item) => {
    if (Array.isArray(item) && deep >= 0) {
      res = res.concat(item.myFlat(deep));
    } else {
      res.push(item);
    }
  });
  return res;
};
kangkang123269 commented 1 year ago
Array.prototype.myFlat = function(depth = 1) {
  if (depth < 1) {
    return this.slice();
  }
  return this.reduce((acc, val) => {
    if (Array.isArray(val)) {
      acc.push(...val.myFlat(depth - 1));
    } else {
      acc.push(val);
    }
    return acc;
  }, []);
};
LifeIsTerrible commented 1 year ago
Array.prototype._flat = function (deep = 1) {
    let result = []
    deep--;
    for (let p of this) {
        if (Array.isArray(p) && deep >= 0) {
            result = result.concat(p._flat(deep))
        } else {
            result = result.push(p)
        }
    }
    return result;
}
Bbbtt04 commented 1 year ago
const arr = [1, [2, 3, [4, 5]], 1, 2, [6, 7]]

Array.prototype.flat = function (deep = 1) {
  let result = []
  for (let item of this) {
    if (Array.isArray(item) && deep >= 1) {
      result = result.concat(item.flat(--deep))
    } else {
      result.push(item)
    }
  }
  return result
}

console.log(arr.flat(2));
xun-zi commented 1 year ago
/**
     * @deep 表示只保证deep + 1层内进行数组扁平化
     * const arr = [1, [2, [3]]];
     *  console.log(arr.flat(1));
    */

    const arr = [1, [2, 3, [4, 5]], 1, 2, [6, 7]]
    Array.prototype.flat = function (deep = 1) {
        //deep表示递归了到的层数,可以想象成deep是嵌套层的下标
        deep--;
        const res = []
        for (let p of this) {
            if (Array.isArray(p) && deep >= 0) {
                //res.concat(p.flat(deep)); concat不会修改原来的值 error
                res = res.concat(p.flat(deep));
            } else {
                res.push(p);
            }
        }
        return res;
    }
    console.log(arr.flat(1));
spicylemonhaha commented 1 year ago

function flatten(input, shallow, strict, output) { output = output || []; var idx = output.length; for(var i = 0, len = input.length; i < len; i ++) { var value = input[i]; if(Array.isArray(value)) { if(shallow) { var j = 0, length = value.length; while(j < length) output[idx ++] = value[j ++]; } else { flatten(value, shallow, strict, output); idx = output.length; } } else if (!strict) { output[idx ++] = value; } } return output; };

cscty commented 1 year ago

Array.prototype.flat = function (deep = 1) { const res = [] for (let item of this) { if (Array.isArray(item) && deep >= 1) { res.push(...item.flat(deep - 1)) } else { res.push(item) } } return res }

QdabuliuQ commented 1 year ago
   Array.prototype.flat = function(deep = 1) {
      if(deep <= 0) return this
      const _flat = (arr, deep) => {
        if(deep <= 0) return arr
        let res = []
        for(let item of arr) {
          if(Array.isArray(item)) {
            res.push(..._flat(item, deep-1))
          } else {
            res.push(item)
          }
        }
        return res
      }
      return _flat(this, deep)
    }
    console.log([1,2,3,4,[5,6,7,[99, 100]], [8,9]].flat(1));
why-ztc commented 1 year ago
const flat = arr => {
  const res = []
  const dfs = list => {
    for (const item of list) {
      if (Array.isArray(item)) {
        dfs(item)
      }else {
        res.push(item)
      }
    }
  }
  dfs(arr)
  return res
}
Aurora-GSW commented 7 months ago
Array.prototype.myFlat = function (deep = 1) {
    let res = []
    deep--
    for (const item of this) {
        if (Array.isArray(item) && deep >= 0) {
            res.push(...item.myFlat(deep))
        } else {
            res.push(item)
        }
    }
    return res
}
yellowsheepGithub commented 2 months ago
function flat(arr, depth) {
    let result = [];
    function flat1(arr, curDepth) {
        for (let i = 0; i < arr.length; i++) {
            if (Array.isArray(arr[i]) && curDepth < depth) {
                flat1(arr[i], curDepth + 1);
            } else {
                result.push(arr[i]);
            }
        }
    }
    flat1(arr, 0);
    return result;
}
jianxingyao commented 1 month ago
Array.prototype.Myflat = function(depth = 1) {
    let result = [];
    for (const item of this) {
        if(Array.isArray(item)){
            depth--;
            if(depth >=0){
                result = result.concat(item.Myflat(depth))
            }
            else{
                result.push(item)
            }
        }
        else{   
            result.push(item)
        }
    }
    return result
}
mosuzi commented 1 month ago
Array.prototype._flat = function (deep = 1) {
    const newArr = []
    const stack = [...this]
    const increaseDeepFlag = Symbol("increase deep")
    while (stack.length) {
        const next = stack.shift()
        if (Array.isArray(next) && deep) {
            Array.prototype.unshift.call(stack, ...next, increaseDeepFlag)
            deep--
        } else if (next === increaseDeepFlag) {
            deep++
        } else {
            newArr.push(next)
        }
    }
    return newArr
}
dizao006 commented 3 weeks ago
Array.prototype.myFlat = function (deep) {
  let result = [];
  deep--;
  for (const ele of this) {
    if (ele instanceof Array && deep >= 0) {
      result.push(...ele.myFlat(deep));
    } else {
      result.push(ele);
    }
  }
  return result;
};

let arr = [
  [1, 2, 3],
  [1, 4],
  [1, 4, [2, 3, 4]],
];
console.log(arr.myFlat(1));
Windseek commented 3 days ago

function flat(arr, dep = 1) { if(dep <=0 ) return arr; let res = []; arr.forEach((item) => { if(Array.isArray(item)) { res = res.concat(flat(item, dep - 1)); } else { res.push(item); } }) return res; }