【问题标题】:Compare array by value or group of values按值或值组比较数组
【发布时间】:2017-12-14 18:52:53
【问题描述】:

假设我有数组 1

const arr1 = [[45, 63],[89],[90]]

和数组 2

const arr2 = [45, 63]

要检查 arr2 或 arr2 中的值是否存在于 arr1 中,执行下一个函数很容易

private contains(arr1, opts) {
    const stringifiedOpts = JSON.stringify(opts);
    return arr1.some(item => JSON.stringify(item) === stringifiedOpts);
}

在这种情况下 contains() 函数将返回 true。

这是第一个最简单的情况。 现在让我们这么说:

arr2 = [45, 63, 90]

function contains() 将返回 false,因为 arr1 不包含 [45, 63, 90] 但包含 [90] 作为不同的数组。在这种情况下,函数应该返回 true,因为 arr1 中存在来自 arr2 的 90

我的问题是我应该在该函数中使用什么样的逻辑来在以下情况下返回 true:

arr2 = [45, 63, 90]

arr2 = [45, 90]

arr2 = [63, 89]

arr2 = [63, 90]

arr2 = [81, 20, 90]

arr2 = [25, 60, 89]

因为 90 或 89 存在于 arr1 但作为不同的数组

欢迎大家在这里提供任何帮助/想法/解决方案。谢谢!

【问题讨论】:

  • Flatten the array 然后简单地搜索它。
  • 为什么[81, 20, 90][25, 60, 89] 应该返回truearr1 没有任何值包含 20812560
  • @Titus 但它包含 90 或 89
  • 我想我误解了描述。我认为该函数只应在arr1 包含arr2 的所有值时返回true,即使它们位于单独的数组中。

标签: javascript arrays ecmascript-6 filtering


【解决方案1】:

这似乎有效:

arr1
  .map(arr => arr.join())
  .some(arr => arr2.join().includes(arr))

【讨论】:

  • 是的,它在所有情况下都按预期工作。哈哈哈,这段代码太短了,我笑得停不下来:D
【解决方案2】:

这是一个没有展平以保持结构的版本,它基本上检查 arr1 中的每个块是否符合 arr2。

const arr1 = [[45, 63],[89],[90]];

function contains(arr, opts) {
    for(let i=0; i<arr.length; i++) {
       let innerArray = arr[i];
       let isThisBlockOk = true;
       for(let j=0; j<innerArray.length; j++) {
           if(opts.indexOf(innerArray[j]) === -1) {
               isThisBlockOk = false;
               break;
           }
       }
       if(isThisBlockOk) return true;
    }
    return false;
}

const listOfArr2 = [
  [45, 63], 
  [45, 63, 90],
  [45, 63, 90],
  [45, 90],
  [63, 89],
  [63, 90],
  [81, 20, 90],
  [25, 60, 89],
  [45, 64, 91],
  [45]
];

listOfArr2.forEach(arr2 => {
  console.log(JSON.stringify(arr2) + ' contains return: '+ contains(arr1, arr2));
});

【讨论】:

  • 好吧,我认为我们不应该使用 flatten 方法,因为如果 arr1 = [[45, 63],[89],[90]] 和 arr2 = [45] 那么它应该是假的,因为在 arr1 中,45 可以和 63 一起使用
  • 我要检查一下,BRB!
  • 问题是arr2总是扁平化,例如arr2 = [45, 63, 90]必须返回true,但如果我理解正确,arr2 = [45, 64, 91]必须返回false。事情来自arr2,我们无法确定如何将其元素分组以匹配arr1,因此我们不得不对其进行暴力破解并测试每个组合。那是你要的吗?在大数据上,性能可能会很丑。
  • 这里还有一件事,假设 arr1 = [[12,43,54,65],[46],[90]] 那么如果 arr2 = [12,43,54,65]如果 arr2 = [12,43,54] 函数应该返回 true 函数应该返回 false 因为在 arr1 这些数字 - 12,43,54 不能没有 65 如果 arr2 = 12,43,54,90 函数应该返回 true 因为90 存在于 arr1 的其他子数组中
  • 这个新版本不是蛮力的,所以性能必须是完全可以接受的,它必须符合你的要求。虽然它很丑,但它当然可以改进,但我现在必须去所以这是第一个版本;)我稍后会尝试花一些时间来改进它!最后检查一下,我添加了一些应该失败的测试用例。
【解决方案3】:

这是你想要的吗?我在猜测并需要您的反馈

const arr1 = [
  [45, 63],
  [89],
  [90]
]

document.write(custom_contains_any(arr1, [63, 88]))
document.write('<br>')
document.write(custom_contains_all(arr1, [63, 90]))

function custom_contains_any(source, search) {
  const s1 = flaten(source)
  const s2 = flaten(search)
  return s2.filter((x) => s1.includes(x)).length
}

function custom_contains_all(source, search) {
  const s1 = flaten(source)
  const s2 = flaten(search)
  return s2.every((x) => s1.includes(x))
}

function flaten(arr) {
  let rtn = []
  arr.forEach((x) => {
    if (Array.isArray(x)) {
      rtn = [...rtn, ...flaten(x)]
      return
    }
    rtn = [...rtn, x]
  })
  return rtn
}

【讨论】:

    猜你喜欢
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-10
    • 2016-05-05
    • 1970-01-01
    • 2019-07-03
    相关资源
    最近更新 更多