【问题标题】:best way to check element combination exist in array in typescript检查打字稿中数组中是否存在元素组合的最佳方法
【发布时间】:2021-09-13 14:23:27
【问题描述】:

我有一个包含一些元素的数组,我想检查数组中是否存在某个元素组合,目标元素后面跟着检查集的任何元素,如果是,则返回 true,否则返回 false。例如, 如果 inputArray 是 ['a', 'b', 'c', 'd'] 并且寻找组合是 ['a', 'd'] 那么它应该返回 true,因为 inputArray 两者的顺序都正确。 如果 inputArray 是 ['d', 'b', 'c', 'd', 'a'] 并且组合是 ['a', 'd'],那么它应该是假的,因为 inputArray 包括这两个元素但在错误的顺序 或

isExist(['a', 'd']) => true 
isExist(['a', 'a', 'd']) => true
isExist(['e', 'd']) => false

我可以使用 Set 和 while 循环 但我想知道是否有更优雅或现代的方式来做?

export function isExist(checkArray): boolean {
  let hasA = false;
  let hasB = false;
  checkingSet = new Set(['b', 'c', 'd'])
  const target = 'a'
  inputArray = [...checkArray]
  while (inputArray && !!inputArray.length) {
    const lastOne = inputArray.pop();
    if (!hasA && !!lastOne) {
      hasA = chekcingSet.has(lastOne);
    }
    if (!hasB && !!lastOne) {
      hasB = lastOne === target;
    }
    if (hasA && hasB) {
      return true;
    }
  }
  return false;
}

【问题讨论】:

  • 我不认为我理解您期望的输出。当 set 为 b,c,d 时,a,d 是如何正确的
  • 什么是target?为什么checkingSet在函数内部定义而不是作为参数传递?
  • 您能否更好地解释一下您的方法实际上要做什么。
  • 为什么要使用双感叹号(!!)?
  • 已更新,@Snirka 需要确保 pop 存在

标签: javascript arrays typescript ecmascript-2020 ecmascript-2021


【解决方案1】:

要检查数组是否包含'a',并且在此'a' 之后至少有一个['b', 'c', 'd'] 在数组中,您可以执行此操作。首先,获取数组中第一个'a'index of,然后在该起始索引之后检查该数组中['b', 'c', 'd']some 值是否为included

function doesExist(arr) {
  const startPos = arr.indexOf('a')
  if (startPos < 0)
    return false
  return ['b', 'c', 'd'].some(char => arr.includes(char, startPos + 1))
}

console.log(doesExist(['a', 'd']))
console.log(doesExist(['a', 'a', 'd']))
console.log(doesExist(['e', 'd']))
console.log(doesExist(['d', 'a']))

【讨论】:

    【解决方案2】:

    这是通用版本,它是 O(n)。

    function doesDupleExistInOrder([el1, el2], arr) {
        let index = arr.indexOf(el1)
        if (index == -1) return false;
        return arr.includes(el2, index + 1)
    }
    
    console.log(doesDupleExistInOrder(["a", "d"], ["a", "b", "c", "d", "e"])); // true
    console.log(doesDupleExistInOrder(["a", "b"], ["a", "b", "c", "d", "e"])); // true
    console.log(doesDupleExistInOrder(["d", "e"], ["a", "b", "c", "d", "e"])); // true
    
    console.log(doesDupleExistInOrder(["d", "a"], ["a", "b", "c", "d", "e"])); // false
    console.log(doesDupleExistInOrder(["d", "a"], ["a"]));                     // false
    console.log(doesDupleExistInOrder(["d", "a"], []));                        // false
    

    如果你想要一个特定的版本,那么只需 curry 通用函数 AKA:

    let doesADExist = arr => doesDupleExistInOrder(["a", "d"], arr);
    console.log(doesADExist(["a", "b", "c", "d", "e"]));  // true
    

    【讨论】:

    • 我认为如果您使用arr.indexOf(el1) 获取第一个 i(并检查 -1)然后使用 arr.includes(el2, i+1) 它会更短且更易于阅读
    • @A_A,也许,但在最坏的情况下需要两次遍历数组,这只需要一次。而且它只有 5 行,所以任何理性的程序员都可以在不到一分钟的时间内弄清楚它在做什么,而且它是一个更快的算法。
    • 我不这么认为。据我了解,indexOf(el1) 会迭代,直到在某个索引i 处找到元素。而arr.includes(el2, i+1) 将在位置i+1 开始迭代。所以在最坏的情况下它应该是 n 步(并且肯定仍然是 O(n))。这些方法也可以通过浏览器进行优化,但我不确定
    • 嗯,好吧,我忘了你可以为包含插入索引。我将编辑我的帖子。
    猜你喜欢
    • 2016-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-20
    • 2019-01-01
    相关资源
    最近更新 更多