лучший способ проверить, существует ли комбинация элементов в массиве в typescript

#javascript #arrays #typescript #ecmascript-2020 #ecmascript-2021

Вопрос:

У меня есть массив с некоторым элементом, который я хочу проверить, существует ли в массиве какая-либо комбинация элементов, за которой следует целевой элемент любого элемента checkingSet, если да, то верните 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 amp;amp; !!inputArray.length) {
    const lastOne = inputArray.pop();
    if (!hasA amp;amp; !!lastOne) {
      hasA = chekcingSet.has(lastOne);
    }
    if (!hasB amp;amp; !!lastOne) {
      hasB = lastOne === target;
    }
    if (hasA amp;amp; hasB) {
      return true;
    }
  }
  return false;
}

 

Комментарии:

1. Я не думаю, что понял, какого результата вы ожидаете. Как это верно для a,d,когда множество равно b,c, d

2. Что такое target ? И почему checkingSet определяется внутри функции, а не передается в качестве аргумента?

3. Не могли бы вы немного лучше объяснить, что на самом деле пытается сделать ваш метод.

4. Почему вы используете двойной восклицательный знак (!!)?

5. обновлено,@Snirka нужно убедиться, что pop существует

Ответ №1:

Чтобы проверить , что массив содержит 'a' , и после этого 'a' хотя бы один из ['b', 'c', 'd'] них находится в массиве, вы можете сделать это. Сначала получите индекс первого 'a' в массиве, затем проверьте, включено ли ['b', 'c', 'd'] какое-либо значение в этот массив после этого начального индекса.

 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
 

Если вам нужна конкретная версия, просто выберите общую функцию, она же:

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

Комментарии:

1. Я думаю, что если вы используете arr.indexOf(el1) для получения первого i (и проверки на -1), а затем arr.includes(el2, i 1) это будет немного короче и легче читать

2. @A_A, возможно, но для этого требуется два цикла по массиву, в худшем случае для этого требуется только один. Кроме того, это всего 5 строк, так что любой разумный программист мог бы понять, что это делает менее чем за минуту, и это более быстрый алгоритм.

3. Я так не думаю. Насколько я понимаю indexOf(el1) , он будет повторяться до тех пор, пока не найдет элемент по некоторому индексу i . И arr.includes(el2, i 1) начал бы повторять в позиции i 1 . Так что в худшем случае это должно быть n шагов (и наверняка еще O(n)). Также эти методы могут быть оптимизированы браузером, но я не уверен в этом

4. Хм, ладно, я забыл, что вы можете подключить индекс для включений. Я отредактирую свой пост.