【问题标题】:convert array into array of subarrays将数组转换为子数组的数组
【发布时间】:2023-03-09 10:00:01
【问题描述】:

我正在寻找将数组转换为子数组的数组。

一个例子是:

let arr = [1, 2, 3, 4, 5, 6, 7, 8]
arr = [[1, 2], [3, 4], [5, 6], [7, 8]]

现在如果这个数组的长度不能被 2 整除

let arr = [1, 2, 3, 4, 5, 6, 7]
arr = [[1, 2], [3, 4], [5, 6], [7]]

我对这个问题的解决方案,IMO 不是很干净

const isPrime = num => {
   for (let i = 2; i < num; i++)
      if (num % i === 0) return false;
    return num > 1;
}
        
const howToGroupArray = (array) => {
    if (array.length === 1) {
        return [1, 0] // group of 1 remainder 0
    }
    else if (!isPrime(array.length) || array.length === 2) {
        return [2, 0] // groups of 2 remainder 0
    }
    else {
        return [2, 1] // groups of 2 and a group of 1
    }

}
        
let values = [1,2,3,4,5,6,7]
let newArray = []
let groups = values.forEach((x, i) => {
    if ((i === 0 || i % 2 === 0) && (i !== (values.length - 1))) {
        newArray.push([x, values[i + 1]])
    }
    else if ((i % 2 === 1) && (i !== (values.length - 1))) {
        null
    }
    else {
        howToGroupArray(values)[1] === 0 ? null : newArray.push([x])
    }
})

【问题讨论】:

标签: javascript performance refactoring code-readability


【解决方案1】:

您可以只使用一个索引进行迭代并将其增加 2。

然后取索引进行切片,并将部分放入结果数组中。

const
    getGrouped = array => {
        let result = [],
            i = 0;
        
        while (i < array.length) result.push(array.slice(i, i += 2));

        return result;
    };

console.log(getGrouped([1, 2, 3, 4, 5, 6, 7, 8]));
console.log(getGrouped([1, 2, 3, 4, 5, 6, 7]));

【讨论】:

    【解决方案2】:

    Ngoc Vuong 写了一篇关于分块数组的nice blog post。他在他的帖子中提供了一些解决方案,我在下面粘贴了这些解决方案。

    遍历数组

    const myArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    const chunkedArray = chunk(myArray, 2);
    console.log(chunkedArray);
    
    function chunk(array, size) {
        const chunkedArray = [];
        for (let i = 0; i < array.length; i++) {
            const last = chunkedArray[chunkedArray.length - 1];
            if (!last || last.length === size) {
                chunkedArray.push([array[i]]);
            } else {
                last.push(array[i]);
            }
        }
        return chunkedArray;
    }

    循环块数

    const myArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    const chunkedArray = chunk(myArray, 2);
    console.log(chunkedArray);
    
    function chunk(array, size) {
        const chunkedArray = [];
        const copied = [...array];
        const numOfChild = Math.ceil(copied.length / size);
        for (let i = 0; i < numOfChild; i++) {
            chunkedArray.push(copied.splice(0, size));
        }
        return chunkedArray;
    }

    使用 slice()

    const myArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    const chunkedArray = chunk(myArray, 2);
    console.log(chunkedArray);
    
    function chunk(array, size) {
        const chunkedArray = [];
        let index = 0;
        while (index < array.length) {
            chunkedArray.push(array.slice(index, size + index));
            index += size;
        }
        return chunkedArray;
    }

    递归方法

    function chunk(array, size) {
        if (!array) return [];
        const firstChunk = array.slice(0, size); // create the first chunk of the given array
        if (!firstChunk.length) {
            return array; // this is the base case to terminal the recursive
        }
        return [firstChunk].concat(chunk(array.slice(size, array.length), size)); 
    }

    【讨论】:

    • 我最喜欢的答案是 hit slice() 版本。感谢您的发现!
    【解决方案3】:

    您可以使用.reduce() 代替.forEach(),如下所示:

            
    let values = [1,2,3,4,5,6,7]
    
    let newArray = values.reduce((res, x, i, orig) =>
      i%2 ? res : [...res, [x, ...orig.slice(i+1, i+2)]]
    , [])
    
    console.log(newArray);

    它使用扩展语法在每个偶数索引上构建结果。奇数索引仅返回当前累积。

    【讨论】:

    • 非常酷,虽然难以消化,解决方案(至少对我而言)。使用 const 而不是 let 用于 values 和 newArray 不是更好吗?挑剔,我知道。
    • @huwiler:是的,const 会更好。我只是使用了 OP 包含的声明,但我肯定更喜欢const
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-13
    • 2011-08-13
    • 2019-04-13
    • 2018-11-08
    相关资源
    最近更新 更多