JavaScript - 检查数组是否仅包含指定的值

7

如何优化一个函数,检查数组是否只包含指定的值,而不使用硬编码的值?

以下是该函数:

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]));
3个回答

21

通过将 arrow 函数作为 参数 传递给 every 方法,您可以实现您的要求。

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]));


谢谢大家的帮助,但我接受这个答案,因为它在 JavaScript 方面更合适且更易于理解。 - gigs

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
点赞你的好方法。我认为你的方法相当于我的答案中的“某些”方法。 - Mihai Alexandru-Ionut
1
@Mihai Alexandru-Ionut 谢谢。基本上应该优先选择你的方法。在 JS 中,使用大型数组进行递归是有问题的...此外,当没有要比较的内容时,这个方法会返回 true,而你的方法应该返回 false,尽管两种方式都可能是可取的。 - Redu

-3

我实际上没有使用过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;
    }

由于这个过程实际上会循环两次数组,因此速度相对较慢,如果您在程序中经常运行这个函数,您可能不希望如此。

否则,也许其他人可以想出解决方法,但您应该能够使用递归来解决。如果您只是搜索一个元素,这非常简单(快速的谷歌搜索应该返回您需要做的内容,至少对于Java而言。再一次,我不熟悉JavaScript……真的应该尽快学习)

以下是一些代码的起点,用于尝试以递归的方式执行此操作 - 无法正常工作,您会得到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));
     }
   }

否则,可能还有另一种方法可以通过二分查找来完成这个任务。(我没有时间测试是否有效,但至少为您提供了这个想法。)
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));
  }
}

相信如果您可以使递归调用起作用,那将是最有效的方法。如果使用大型数组,则下一个最有效的方法应该是二分搜索。最后,我提出的第一种方法将是最慢的。

1
OP 寻求 JavaScript 帮助,他并没有寻求 Java 帮助。 - The epic face 007

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接