【问题标题】:How to get all pairs of array JavaScript如何获取所有数组 JavaScript 对
【发布时间】:2014-04-29 06:29:01
【问题描述】:

我需要使用所有可用的数组元素对来调用函数。像这样:

[1, 2, 3].pairs(function (pair) {
  console.log(pair); //[1,2], [1,3], [2,3]
});

【问题讨论】:

标签: javascript


【解决方案1】:

您应该尝试向我们展示您自己解决了问题,而不是仅仅向我们询问答案,但这是一个有趣的问题,所以在这里:

Array.prototype.pairs = function (func) {
    for (var i = 0; i < this.length - 1; i++) {
        for (var j = i; j < this.length - 1; j++) {
            func([this[i], this[j+1]]);
        }
    }
}

var list = [1, 2, 3];
list.pairs(function(pair){
    console.log(pair); // [1,2], [1,3], [2,3]
});

http://jsfiddle.net/J3wT5/

【讨论】:

  • 我不是很好的专家,抱歉。谷歌搜索没有帮助;)非常感谢。
【解决方案2】:

感谢 ECMAScript 标准的不断发展..

let pairs = (arr) => arr.map( (v, i) => arr.slice(i + 1).map(w => [v, w]) ).flat();

pairs([1, 2, 3, 4, 5]);

【讨论】:

    【解决方案3】:
    function pairs(arr) {
        var res = [],
            l = arr.length;
        for(var i=0; i<l; ++i)
            for(var j=i+1; j<l; ++j)
                res.push([arr[i], arr[j]]);
        return res;
    }
    pairs([1, 2, 3]).forEach(function(pair){
        console.log(pair);
    });
    

    【讨论】:

      【解决方案4】:

      这是一个没有突变的 ES6 风格的变体:

      const pairsOfArray = array => (
        array.reduce((acc, val, i1) => [
          ...acc,
          ...new Array(array.length - 1 - i1).fill(0)
            .map((v, i2) => ([array[i1], array[i1 + 1 + i2]]))
        ], [])
      ) 
      
      const pairs = pairsOfArray(['a', 'b', 'c', 'd', 'e'])
      console.log(pairs)
      
      // => [['a','b'], ['a','c'], ['a','d'],['a','e'],['b','c'],['b','d'],['b','e'],['c','d'],['c','e'],['d','e']]

      【讨论】:

        【解决方案5】:

        flatMap 现在在 ECMAScript 中可用,有一个非常简单且可读的选项可以在 Javascript 中查找列表中的项目对,而无需循环:

        const pairs = (a) => {
            
            return a.flatMap( (x) => {
                return a.flatMap( (y) => {
                    return (x != y) ? [[x,y]] : []
                });
            });
        }
        

        调用pairs([1,2,3])会输出:

        [ [ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 2, 3 ], [ 3, 1 ], [ 3, 2 ] ]
        

        简单、易读且实用。

        编辑:我最初将这个问题读作“如何获得所有对”,我认为它包括反向对,上面的例子就是这样。要返回没有倒序对的列表,我们可以用reduce() 取出这些:

        const isInArray = (a, value) => {
            if (
                a.map((x) => {
                    if (x.toString() == value.toString()) return true;
                }).includes(true)
            ){
                return true;
            }
        };
        
        const reducedPairs = (a) => {
            
            return a.flatMap( (x) => {
                return a.flatMap( (y) => {
                    return (x != y) ? [[x,y]] : []
                });
            }).reduce( (unique, current) => {
                if (!isInArray(unique, current.slice().reverse())) unique.push(current);
                return unique;
            }, []);
        
        }
        

        请注意,这使用字符串比较来检查数组是否相等,因为[1,2] == [1,2]false。这适用于原始问题中的用例,但对于更复杂的示例,可能需要另一种检查重复项的方法。

        【讨论】:

          【解决方案6】:

          这是我使用 ES6 能找到的最简洁的解决方案。它根据索引并使用 flatMap 函数生成唯一的对。

          const uniquePairs = (arr) => 
            arr.flatMap((item1, index1) => 
              arr.flatMap((item2, index2) => 
                (index1 > index2) ? [[item1,item2]] : []
              )
            )
          
          uniquePairs([1,2,3])
          // [[2, 1], [3, 1], [3, 2]]
          

          flatMap - 将元素返回到一个数组中,并具有能够完全删除空数组的好处。这就是让我们的值为[] 的三元组消失的原因!

          map一样,它可以返回索引,通过比较两个项目的索引,我们可以避免重复(第一个索引必须大于第二个才能添加元素)。

          三元组让我们进行比较,如果为假则返回一个空数组(第二个 flatMap 完全忽略了该数组)。

          通过将每个 flatMap 更改为 map,您可以更好地了解每个 flatMap 正在完成的工作 - 所以我鼓励您尝试更改它!

          【讨论】:

          • 您的回答很好,但显然与 Harry 的回答重复:stackoverflow.com/a/65064026/3933603
          • 虽然 Harry's 很好,但它并不能防止重复的唯一列表。相反,它提供每个配对,包括重复项。然后它使用reduce(作为扩展)来提供唯一的项目——这很冗长,因为你可以简单地通过比较索引值来做到这一点(这是Harry在他的解决方案中没有做的事情)。我知道表面上它们看起来很相似,但在说它们“显然是重复的”之前,你应该比较他的原始解决方案和我的输出。
          • 你是对的,我很抱歉粗鲁的评论。感谢您在这里的详细解释和出色的工作!
          【解决方案7】:

          如果您也在寻找反向对 - 与上面 @Oriol 的答案不同 - 这是一个包含所有原始对 + 所有反向原始对的版本:

          function allPairs (arr) {
            let pairs = [];
            for (let i = 0; i < arr.length; i++) {
              for (let j = i + 1; j < arr.length; j++) {
                pairs.push([arr[i], arr[j]]);
              }
            }
            let copy = pairs;
            pairs = JSON.stringify(pairs);
            let reversed = [];
            copy.forEach((value) => {
              reversed.push(value.reverse());
            })
            let final = [];
            final.push(JSON.parse(pairs).concat(reversed));
            return final[0];
          }
          console.log(allPairs([1, 2, 3, 4, 5]));

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-06-18
            • 2014-06-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-08-22
            • 2018-07-21
            相关资源
            最近更新 更多