我正在尝试使用 reduce... 重新组合一组数组,但失败了

Posted

技术标签:

【中文标题】我正在尝试使用 reduce... 重新组合一组数组,但失败了【英文标题】:I am trying to regroup an array of arrays using reduce... and failing 【发布时间】:2022-01-13 18:29:13 【问题描述】:

所以,我正在尝试重新组合元素……以一种难以解释的方式。这是输入和预期输出的示例...

zip(['fred', 'barney'], [30, 40], [true, false]); 

should output...

→ [['fred', 30, true], ['barney', 40, false]]

我认为 reduce 是合适的,因为我应该采用多个数组并将其转换为包含与输入数组长度相同数量的数组的单个数组...

这就是我正在做的事情......它不起作用,但我相信我接近正确的想法!

function zip(array) 
    return array.reduce((acc, next) => 
        // get length of next array to use in for-loop...
        let numOfElem = next.length
        // use a for loop to access different indexed arrays...
        for (let i = 0; i < numOfElem; i++) 
            // this is supposed to push the appropriate element in the next array to the accumulator array's corresponding index...
            acc[i].push(next[i]);
        
        return acc;
    , [])


const result = zip(['fred', 'barney'], [30, 40], [true, false]); 
console.log(result);

我相信我试图错误地推动? acc[i].push(next[i]) 背后的想法是 acc[i] 将根据输入的长度创建必要数量的数组数组。代码不起作用。我只是在寻找一种让它工作的方法,即使是通过不同的方法!

感谢您花时间阅读本文以及任何反馈、提示或技巧!

【问题讨论】:

zip 在您的示例中应该采用多个数组,但是,实现只需要一个。哪些应该是正确的? 我对你的意思有点困惑......你能解释一下吗? zip(['fred', 'barney'], [30, 40], [true, false]); 正在使用三个数组调用 zip。您的 function zip(array) 显然需要一个数组。这两者是不相容的。只有其中一个是正确的。 哦...有道理...我猜 reduce 可能不会起作用? 现在它只会遍历第一个数组。因此我的问题是 - 您要么打算传递包含其他数组的 one 数组,要么想要接受可变数量的数组并遍历它们。哪一个? 【参考方案1】:

您可以减少参数并映射相同索引的部分结果。

const
    zip = (...array) =>
        array.reduce((r, a) => a.map((v, i) => [...(r[i] || []), v]), []);

console.log(zip(['fred', 'barney'], [30, 40], [true, false]));
.as-console-wrapper  max-height: 100% !important; top: 0; 

不等长数组的方法。

const
    zip = (...array) => array.reduce((r, a, i) => 
        while (r.length < a.length) r.push(Array(i).fill(undefined));
        return r.map((b, j) => [...b, a[j]]);
    , []);

console.log(zip(['fred', 'barney'], [30, 40, 3, 4, 5, 6, 7], [true, false, 'don\'t know']));
.as-console-wrapper  max-height: 100% !important; top: 0; 

【讨论】:

谢谢,这帮助我走上了正轨。我的问题是我需要让它处理与最大数组相同数量的元素。我想我应该说我需要考虑不同的数组长度。例如... zip(['moe', 'larry', 'curly'], [30, 40, 50], [true] 理论上会输出 [ [ 'moe', 30, true ], [ 'larry' , 40, undefined ], ['curly', 50, undefined ] ] @DaShaman,请参阅编辑。【参考方案2】:

这样的?

const zip=(arr)=>
    let res=[]
    arr[0].forEach((el,k) => 
        res.push(arr.reduce((acc, curr)=>
            acc.push(curr[k])
            return acc
        ,[]))  
    );
  return res

console.log(zip([['moe', 'larry', 'curly'], [30, 40, 50], [true]]))

【讨论】:

谢谢!我最终用 map 方法解决了它......但是很高兴看到一个符合我最初想法的替代解决方案!【参考方案3】:

function zip(...arrays) 
  const flattened = arrays.flatMap(item => item)
  const result = []
  for (let index = 0; index <= arrays.length; index++) 
    result[index] = []
    for (let step = index; step < flattened.length; step = step + arrays[0].length) 
      result[index][(step - index) / arrays[0].length] = flattened[step]
    
  
  return result


const arr1 = [ 'fred', 'barney', 'alpha', 'beta' ]
const arr2 = [ 30, 40, 50, 60 ]
const arr3 = [ true, false, null, true ]

console.log(zip(arr1, arr2, arr3))

【讨论】:

以上是关于我正在尝试使用 reduce... 重新组合一组数组,但失败了的主要内容,如果未能解决你的问题,请参考以下文章

使用reduce组合函数

PHP如何对一组数进行重新排列(冒泡算法)

无法在按钮点击时重新加载 UICollectionView

使用 Redux 如何阻止 reducer 中的 switch 增长?

python reduce找到集合的并集

使用一组字符串生成所有可能的组合