Javascript - Проверьте, содержит ли массив только указанные значения

1

Как я могу оптимизировать функцию, которая проверяет, содержит ли массив только указанные значения, не использующие жестко заданные значения?

Вот функция

function containOnly(value1, value2, array){
  var result;

  for(i = 0; i < array.length; i++){
    if(array[i] != value1 && array[i] != value2){
      result = 0;
      break;
    } else
      result = 1;
  }

  if(result === 0)
    return false;
  else
    return true;
}

console.log(containOnly(1, 2, [2,1,2]));

Эта функция вернет true, если массив содержит указанные значения. В этой функции я использую оператор if для сравнения двух значений, но как я могу использовать массив значений вместо переменных, если я хочу использовать более двух значений? Например:

console.log(containOnly([1, 2, 3], [2,1,2,3,5]));
Теги:
arrays

3 ответа

2
Лучший ответ

Вы можете выполнить свое требование, используя every метод, передав функцию arrow качестве аргумента.

Метод every() проверяет, прошли ли все элементы массива тест, реализованный предоставленной функцией.

function containsOnly(array1, array2){
  return array2.every(elem => array1.includes(elem))
}
console.log(containsOnly([1, 2, 3], [2,1,2,3,5]));
console.log(containsOnly([1, 2], [2,1,2,1,1]));

Другое решение - использовать some метод.

function containsOnly(array1, array2){
  return !array2.some(elem => !array1.includes(elem))
}
console.log(containsOnly([1, 2, 3], [2,1,2,3,5]));
console.log(containsOnly([1, 2], [2,1,2,1,1]));
  • 0
    Спасибо всем за помощь, но я принимаю этот ответ, потому что этот больше подходит с точки зрения javascript и легче для понимания.
1

Вы можете просто && вверх .includes().

var arr     = [0,1,3,5,7,9,2,6,8,11,32,53,22,37,91,2,42],
    values1 = [0,2,37,42],
    values2 = [91,99,9],
    checker = ([v,...vs], a) => v !== void 0 ? a.includes(v) && checker(vs, a)
                                             : true;
console.log(checker(values1,arr));
console.log(checker(values2,arr));

Это также эффективно, чем .reduce() поскольку оно прекратит рекурсию после получения первого false значения.

  • 1
    Upvote для вашего хорошего решения. Я думаю, что ваш метод эквивалентен some методу, как в моем ответе.
  • 1
    @Mihai Alexandru-Ionut Спасибо .. Разница в том, что в основном ваша должна быть предпочтительной. В JS рекурсия с большими массивами проблематична ... Также этот возвращает true когда нечего сравнивать, и ваш должен возвращать false хотя оба пути могут быть желательны.
0

Я на самом деле не использовал JS, но Java очень хорошо переводится. Вот какой код работает, но это не так эффективно:

    public boolean containsOnly(int[] findVals, int[] searchArray){
         for(int i=0; i < searchArray.length; i++){
              for(int j=0; j < findVals.length; j++){
                   if(searchArray[i] == findVals[j]){
                        return true;
                   }
              }
         }
         return false;
    }

Поскольку это эффективно циклически выполняется через оба массива дважды, это относительно медленный процесс, который вам может не понадобиться, если вы много работаете с этой функцией в своей программе.

В противном случае, возможно, кто-то еще может это понять, но вы должны иметь возможность использовать рекурсию для решения этой проблемы. Это очень просто, если вы просто ищете один элемент (быстрый поиск в Google должен вернуть то, что вам нужно для его выполнения, по крайней мере для Java. Еще раз, я незнаком с JS... действительно должен скоро это узнать)

Здесь начальная точка для некоторого кода, чтобы попытаться сделать это рекурсивно - не работает, вы получаете исключение NullPointerException - кто-то помогает в этом?

    class Searcher{
       public boolean contains(int[] findVals, int[] searchArray){
          int pos = 0;
          while(pos < findVals.length){
          if(searchArray.length==0){
             return false;
          }
          else if(searchArray[0] == findVals[pos]){
             return true;     
          }
          else{
             return contains(findVals, shorten(searchArray));
          }
       }
       return false;
     }

     public int[] shorten(int[] array){
        int[] temp = new int[array.length-1];
        for(int i=0; i<temp.length; i++){
           temp[i] = array[i+1];
        }
        return temp;
     }

     public void main(String[] args){
        int[] findVals = new int[]{1,2,3};
        int[] searchArray = new int[]{2,1,2,3,5};
        System.out.println(contains(findVals, searchArray));
     }
   }

В противном случае может быть еще один способ сделать это через binarySearch. (у меня не было времени проверить, работает ли это или нет, но, по крайней мере, идея присутствует для вас.)

import java.util.Arrays;

class Searcher{
  private int binarySearcher(int[] searchArray, int find){
      int left = 0;
      int mid;
      int right = searchArray.length - 1;
      while(true){
        if(left > right){
          mid = -1;
          break;
        }
        else{
          mid = (left + right) / 2;
          if(find < searchArray[mid]){
            right = mid -1;
          }
          else if(find > searchArray[mid]){
            left = mid + 1;
          }
          else{
            break;
          }
        }
      }
      return mid;
    }

  public boolean searchFor(int[] findVals, int[] searchArray){
    Arrays.sort(searchArray);
    Arrays.sort(findVals);
    for(int i=0; i < findVals.length; i++){
      int test = binarySearcher(searchArray, findVals[i]);
      if(test >= 0){
        return true;
      }
    }
    return false;
  }

  public void main(String[] args){
    int[] findVals = new int[]{1,2,3};
    int[] searchArray = new int[]{2,1,2,3,5};
    System.out.println(searchFor(findVals, searchArray));
  }
}

Довольно уверен, что если вы сможете получить рекурсивный призыв к работе, это будет наиболее эффективным. Следующим наиболее эффективным должен быть двоичный поиск (если у вас большие массивы). Наконец, первый предложенный мной метод был бы самым медленным.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню