【问题标题】:Unable to properly get common elements between 4 arrays无法正确获取 4 个数组之间的公共元素
【发布时间】:2019-09-03 17:30:46
【问题描述】:

我正在尝试使用此代码获取恰好位于 4 个数组中的每个数组中的常见元素。

但它看起来像是在计算两个或三个数组中常见的任何元素。但我需要获取在所有四个数组中重复的公共元素。我该如何解决这个问题?

let newArr = [];

function common(arr1, arr2, arr3, arr4) {

  newArr = arr1.filter(function(v) {
    return arr2.indexOf(v) >= 0;
  })
  newArr.concat(arr2.filter(function(v) {
    return newArr.indexOf(v) >= 0;
  }));
  newArr.concat(arr3.filter(function(v) {
    return newArr.indexOf(v) >= 0;
  }));
  newArr.concat(arr4.filter(function(v) {
    return newArr.indexOf(v) >= 0;
  }));
}

common([1, 2, 6, 5, 9], [1, 2, 3, 6, 5, 9], [6, 5, 4, 5], [8, 2, 1, 6, 4]);

$('div').text(newArr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div></div>

【问题讨论】:

  • 较新版本的 javascript 提供 Array.prototype.includes,因此如果您有一个数组并想知道它是否有值,theArray.includes(value) 将返回 true 或 false。如果您过滤第一个数组,并仅返回其他数组中包含的元素,则相当简单。即使没有includes() 方法,使用 indexOf 也可以做同样的事情

标签: javascript jquery arrays ecmascript-6


【解决方案1】:

此版本的解决方案允许您传入不确定数量的数组。只要它没有找到该数字不在的数组,它就会在结果中包含该数字。

function common() {
  var firstArray = arguments[0];
  var otherArrays = Array.prototype.slice.call(arguments, 1);
  
  if (!otherArrays) return firstArray;
  
  return firstArray.filter(function(element){
    return otherArrays.filter(function(otherArray){
      return otherArray.indexOf(element) < 0;
    }).length == 0;
  });
}

var result = common([1, 2, 6, 5, 9], [1, 2, 3, 6, 5, 9], [6, 5, 4, 5], [8, 2, 1, 6, 4]);

$('div').text(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div></div>

如果你知道你有Array.prototype.every 的浏览器支持,这个逻辑可以减少一些。

function common() {
  var firstArray = arguments[0];
  var otherArrays = Array.prototype.slice.call(arguments, 1);
  
  if (!otherArrays) return firstArray;
  
  return firstArray.filter(function(element){
    return otherArrays.every(function(otherArray){
      return otherArray.indexOf(element) > -1;
    });
  });
}

var result = common([1, 2, 6, 5, 9], [1, 2, 3, 6, 5, 9], [6, 5, 4, 5], [8, 2, 1, 6, 4]);

$('div').text(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div></div>

【讨论】:

  • 这是个好主意。我很想过滤 otherArrays.every(arr =&gt; arr.includes(element)) 而不是内部过滤器,这将允许它提前退出并避免创建临时数组。
  • 我需要检查浏览器对every() 的支持。我试图将其保持在相对较低的水平。
  • IE 9,还不错。可以使用。
【解决方案2】:

您可以像使用筛子一样使用reduce() 来不断过滤过滤后的结果,就像使用includes() 一样

let s = [[1, 2, 6, 5,9], [1, 2, 3, 6, 5,9], [ 6, 5, 4, 5], [8, 2, 1, 6, 4]];

let common = s.reduce((common, arr) => common.filter(item => arr.includes(item)))
console.log(common)

【讨论】:

    【解决方案3】:

    像这样使用filter 和indexOf 调用:

    let newArr = [];
    
    function common(arr1, arr2, arr3, arr4) {
      newArr = arr1.filter(function(e) {
        return arr2.indexOf(e) > -1 && arr3.indexOf(e) > -1 && arr4.indexOf(e) > -1;
      });
    }
    
    common([1, 2, 6, 5, 9], [1, 2, 3, 6, 5, 9], [6, 5, 4, 5], [8, 2, 1, 6, 4]);
    
    $('div').text(newArr);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div></div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-30
      • 2015-07-20
      • 1970-01-01
      • 2020-02-23
      • 1970-01-01
      • 2011-01-20
      • 1970-01-01
      相关资源
      最近更新 更多