every 和some_如何使用.every()和.some()操纵JavaScript数组

every 和some

介绍 (Introduction)

ES5 and ES6 brought many changes to JavaScript, including better ways of working with a collection of data expressed as arrays. While the language has significantly improved support for declarative data manipulation on arrays and many modern browsers support them, only a limited subset of array capabilities are commonly used. In particular, the .every() and .some() functions can improve how developers manipulate arrays, and potentially give them performance gains.

ES5和ES6对JavaScript进行了许多更改,包括更好的处理以数组表示的数据集合的方法。 尽管该语言大大改进了对数组中声明性数据操作的支持,并且许多现代浏览器都支持它们,但是通常仅使用有限的数组功能子集。 特别是.every().some()函数可以改善开发人员处理数组的方式,并有可能提高性能。

This article will show that the prominent JavaScript array functions are .map(), .filter(), and .reduce(), and will then go through examples of instances in which .every() and .some() would save computing power over the more prominent solutions.

本文将表明,突出JavaScript阵列功能.map() .filter().reduce()然后将通过实例的实例去其中.every().some()将节省计算能力在更突出的解决方案上。

.map() .filter().filter() .reduce() :突出JavaScript数组函数 (.map(), .filter(), and .reduce(): The Prominent JavaScript Array Functions)

Usage of .map(), .filter(), and .reduce() are very common. For the purpose of this article, let’s call these three functions MFR.

的使用.map() .filter().reduce()是很常见的。 出于本文的目的,我们将这三个函数称为MFR

These functions have gained more prominence over the other functions for manipulating array data in JavaScript. Google Trends, for example, shows more active searches for MFR than a sampling of other functions:

这些功能比其他在JavaScript中处理数组数据的功能更加突出。 例如,与其他功能示例相比, Google趋势显示对MFR的活跃搜索更多:

Google Search also shows that search queries for MFR produce far more results.

Google搜索还显示,针对MFR的搜索查询可产生更多结果。

Search results for .filter() are as much as over 74M. This is 99.97% higher than results for .every(), and 99.98% higher than results for .some(). This means people are talking, writing, and teaching more MFR, which suggests more usage over time.

.filter()搜索结果多达74M。 这比.every()结果高99.97%,比的结果高99.98%。 some() 。 这意味着人们正在谈论,写作和教学更多的MFR ,这表明随着时间的推移会更多地使用它。

.every().some()的好处 (The Benefits of .every() and .some())

In JavaScript, it is generally taught to limit computations on arrays to iteration (.forEach) and transformation (.map, .filter, .reduce - a.k.a MFR) operations. This could lead to computations that could be done with .some() or .every() to be forced into MFR , especially a sequence of .filter() followed by a .reduce().

在JavaScript中,通常会教导将数组的计算限制为迭代(.forEach)和转换(.map,.filter,.reduce-aka MFR )操作。 这可能导致可以将.some().every()强制执行到MFR中的计算 ,尤其是一系列.filter()后跟一个。 reduce()

Almost every usage of MFR where you need to exit early and not comb through the entire collection is a prime candidate for .some() or .every(), because they both short-circuit and exit the array iteration as early as possible, instead of running till the end and potentially wasting compute resources.

需要提前退出而不梳理整个集合的MFR几乎所有用法都是.some().every()的主要候选者,因为它们都会短路并尽可能早地退出数组迭代。运行到最后并可能浪费计算资源。

In a time when we are building more complex apps and shipping more bytes to the client, resulting in significant overhead to parse JavaScript (see TTI, anything we can do to have three iterations (due to short-circuit) instead of thirty is highly welcome.

在我们构建更复杂的应用程序并将更多字节发送到客户端的时代,解析JavaScript会产生大量开销(请参阅TTI ,我们可以做的任何事情都可以做到三遍迭代(由于短路)而不是三十遍) 。

Array.prototype.every() (Array.prototype.every())

The every() method allows us to establish if every element within an array meets a certain requirement. It stops evaluating the array (short circuits) the first time it finds an element that does not satisfy the given requirement.

every()方法允许我们确定数组中的每个元素是否满足特定要求。 第一次发现不满足给定要求的元素时,它将停止评估数组(短路)。

Array.prototype.some() (Array.prototype.some())

The some() method allows us to establish if some (at least one) elements within an array meets a certain requirement. It stops evaluating the array (short circuits) the first time it finds an element that does satisfy the given requirement.

some()方法允许我们确定数组中的某些 (至少一个)元素是否满足特定要求。 第一次发现不满足给定要求的元素时,它将停止评估数组(短路)。

一个例子,两种情况 (One Example, Two Scenarios)

Let’s say you have been asked to write a simple add() function to add a bunch of integers. The function should expect to be given any number of integers to be added and it should return their sum after computing the addition.

假设您被要求编写一个简单的add()函数来添加一堆整数。 该函数应该期望有任意数量的整数相加,并且应该在计算加法后返回它们的总和。

The following are two ways to complete this task.

以下是完成此任务的两种方法。

方案一 (Scenario One)

If the add() function is given mixed input (e.g, integers, floats, undefined, strings, etc.), it should proceed with just the integers and return the sum from adding them. We could implement our add() function this way:

如果给add()函数提供了混合输入(例如,整数,浮点数,未定义,字符串等),则它应仅处理整数,并从相加后返回总和。 我们可以这样实现add()函数:

const add = (...entries) => {
  return entries
    .filter(Number.isInteger)
    .reduce((sum, int) => {
      return sum + int;
    }, 0);
};

Since this scenario expects the add() function to compute the sum from whatever integers exists within the given inputs, one might implement the function like we have in the previous code block. We first use .filter() to extract only the integers and then compute the sum with a .reduce(). The .filter() operation will however iterate over the entire array even if there are no integers within it, wasting compute resources.

由于这种情况要求add()函数根据给定输入中存在的任何整数来计算总和,因此可以像上一个代码块中那样实现该函数。 我们首先使用.filter()只提取整数,然后计算用的总和.reduce() 但是,即使内部没有整数, .filter()操作也会遍历整个数组,这会浪费计算资源。

One can also argue that we can get a better solution like this:

也可以说我们可以获得这样更好的解决方案:

const add = (...entries) => {
  return entries.reduce((sum, entry) => {
    if(Number.isInteger(entry)) {
      return sum + entry;
    }
    return sum;
  }, 0);
};

This take on add() is a little better because, unlike the first one that iterates to identify valid data and then further iterates to compute the result based on the valid data, now there is just one block of iteration. However, we are still running through to the end of the array even if there might be no integers within it.

add()做法要好一些,因为与第一个迭代以识别有效数据然后进一步迭代以基于有效数据计算结果的方法不同,现在只有一个迭代块。 但是,即使数组中可能没有整数,我们仍要遍历到数组的末尾。

We need a way to first tell if the gathered inputs have at least one integer. Since we are trying to find the sum from the inputs, we actually need at least two integers in there. We will proceed to reduce the inputs to the sum of the integers if we can find two or more integers.

我们需要一种方法来首先判断收集的输入是否至少有一个整数。 由于我们试图从输入中查找总和,因此实际上我们至少需要两个整数。 如果可以找到两个或更多整数,我们将继续将输入减少为整数之和。

Lets use .some() so ensure this condition is met:

让我们使用.some()以确保满足此条件:

const add = (...entries) => {
  let theSum = 0;
  if(hasTwoOrMoreInts(entries)){
    // there are >= 2 integers, lets sum them
    theSum = entries.reduce((sum, entry) => {
      if(Number.isInteger(entry)) {
        return sum + entry;
      }
      return sum;
    }, 0);
  }
  return theSum;
};

Now we have a condition that prevents the sum calculation unless we are sure there are two or more integers. We are doing this with a hasTwoOrMoreInts() function that we will be creating in the following:

现在,我们有一个条件阻止总和的计算,除非我们确定有两个或多个整数。 我们使用hasTwoOrMoreInts()函数来执行此操作,该函数将在下面创建:

const hasTwoOrMoreInts = (entries) => {
  let lastIndex = -1;
  let hasMinimumIntsCount = false;

  const hasAnInt = entries.some((entry, index) => {
    lastIndex = index;
    return Number.isInteger(entry);
  });

  if(hasAnInt === true) {
    // we've got one int, is there another?
    const hasMoreInts = entries.slice(lastIndex + 1).some(Number.isInteger);
    hasMinimumIntsCount = (hasMoreInts === true) && hasAnInt;
  }

  return hasMinimumIntsCount;
};

方案二 (Scenario Two)

If the add() function can receive mixed input (such as integers, floats, undefined, strings, etc.) but needs to only proceed with computing the sum of the given inputs if all the inputs are integers, a common approach influenced by the prominence of MFR might look like this:

如果add()函数可以接收混合输入(例如整数,浮点数,未定义的字符串等),但是如果所有输入均为整数,则仅需继续计算给定输入的总和,则该通用方法会受到MFR的突出可能如下所示:

const add = (...entries) => {
  let theSum = 0;
  const nonInts = entries.filter(entry => !Number.isInteger(entry));
  if(nonInts.length === 0) {  // are there non-ints?
    theSum = entries.reduce((sum, int) => {
      return sum + int;
    }, 0);
  }
  return theSum;
}

Again entries.filter() attempts to see if there are invalid inputs by iterating the entire entries array to gather every input that is not an integer. If there are no invalid inputs (nonInts.length === 0), we compute the sum with .reduce(). This would have made sense if we needed the total number of all invalid inputs or all the inputs themselves. Otherwise, we should be looking for the first invalid input and deciding what to do next from there.

entries.filter()再次尝试通过遍历整个entries数组以收集每个不是整数的输入来查看是否存在无效输入。 如果没有无效输入( nonInts.length === 0 ),则使用.reduce()计算总和。 如果我们需要所有无效输入的总数或所有输入本身的数量,这将是有道理的。 否则,我们应该寻找第一个无效输入,并从那里决定下一步要做什么。

Like .some(), .every() will act on the least information necessary. In this case, once it finds an input that is not an integer, it will look no further (by exiting with a return of false) and allow us to proceed with the next important thing.

.some().every()将作用于所需的最少信息。 在这种情况下,一旦找到不是整数的输入,就不会再看了(通过返回false退出),并允许我们继续进行下一个重要的事情。

Let’s see how .every() does this for us:

让我们看看.every()如何为我们做到这一点:

const add = (...entries) => {
  let theSum = 0;
  const areAllInts = entries.every(Number.isInteger);
  if(areAllInts === true) {  // are these indeed all ints?
    theSum = entries.reduce((sum, int) => {
      return sum + int;
    }, 0);
  }
  return theSum;
};

Since entries.every() will return false as soon as it finds what is not an integer, we are able to exit further tests for invalid elements within entries, freeing up resources that might be needed to give a mobile user a smooth scrolling experience.

由于entries.every()一旦发现不是整数的整数,将立即返回false ,因此我们可以退出进一步测试entries无效元素,从而释放可能需要的资源,以使移动用户获得流畅的滚动体验。

一个更实际的例子 (A More Practical Example)

Programmers don’t often write add() functions that often from day to day, so let’s look at a real-world example: applying .every() and .some() to a hypothetical HTML form validation.

程序员并不经常每天写add()函数,因此让我们看一个真实的示例:将.every().some()应用于假设HTML表单验证。

We want to submit the form only after all required data have been obtained and validated from the form. We equally want at least one of the optional data to be filled in:

我们希望仅在从表格中获取并验证了所有必需数据后才提交表格。 我们同样希望至少填写一个可选数据:

const requiredFields = Array.of(
  isFirstNameValid(),
  isLastNameValid(),
  isEmailValid(),
  isAboutMeValid()
);

const optionalFields = Array.of(
  isTwitterValueValid(),
  isFacebookValue(),
  isGoogleplusValueValue()
);

const isValid = (inputStatus) => inputStatus === true;

if(requiredFields.every(isValid) && optionalFields.some(isValid)) {
  // all required fields are valid
  // and at least one social media field is valid
  // lets proceed to submit the form now
} else {
    // lets tell the user we are serious here
    // this will happen really fast since we are short-circuiting 
    // with .some and .every above
}

As seen above, all the functions within Array.of() are doing the validation for specific form fields, and then returning either true or false. Since Array.of() is a factory for constructing arrays from the parameters it is given (the validation functions in our case), this means optionalFields can eventually look like [true, false, false]. This way, if any value in requiredFields is false, or if none of optionalFields is true, we do not submit the form. The form submission is decided with the shortest path of execution.

如上所示, Array.of()中的所有函数都在对特定表单字段进行验证,然后返回truefalse 。 由于Array.of()是根据给定参数构造数组的工厂(在本例中为验证函数),因此这意味着optionalFields最终看起来可能像[true, false, false] 。 这样,如果requiredFields任何值为false,或者optionalFields任何一个都不为true,则我们不会提交表单。 表单提交是通过最短的执行路径来决定的。

结论 (Conclusion)

This exploration helped reveal how prominent MFR has become. It also sheds light on why .every() and .some() can give you more efficient strategies for manipulating arrays.

这项探索帮助揭示了MFR的重要性 。 它还.every()了为什么.every().some()可以为您提供更有效的数组处理策略。

Here are some possible scenarios to promote or adopt .some() or .every() over MFR in your Javascript codebase:

以下是一些可能推广或采用的方案。 Java代码中MFR上的 some().every()

  • A .filter() immediately followed by .forEach(), .map(), .reduce(), or any chained combination involving them.

    .filter()紧跟.forEach() .map() .reduce()或者涉及它们的任何组合链式。

  • A .filter() immediately followed by a condition examining the result of the invocation, and where the body of the condition contains a .forEach() , .map(), .reduce(), or any chained combination involving them, acting on the result from the .filter().

    .filter()紧跟通过检查调用的结果的条件,并且,其中的病症的体内含有.forEach() .map() .reduce()或任何组合链式涉及它们,作用于.filter()的结果。

For these and other relevant scenarios, exiting the checks as soon as possible will optimize your resources.

对于这些和其他相关方案,尽快退出检查将优化您的资源。

翻译自: https://www.digitalocean.com/community/tutorials/using-every-and-some-to-manipulate-javascript-arrays

every 和some

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
some和every方法是JavaScript数组的两个常用方法,用于判断数组中的元素是否满足指定条件。 some方法会遍历数组中的每个元素,只要有一个元素满足条件,就返回true;如果所有元素都不满足条件,则返回false。\[1\]例如,对于数组\[2, 4, 6, 8, 10\],使用some方法判断是否存在元素小于5的情况,结果为true,因为数组中的2小于5。 every方法也会遍历数组中的每个元素,但要求所有元素都满足条件,才返回true;只要有一个元素不满足条件,就返回false。\[2\]例如,对于数组\[2, 4, 6, 8, 10\],使用every方法判断是否所有元素都小于20,结果为true,因为所有元素都小于20。 需要注意的是,当遍历到某个元素不满足条件时,some方法会停止遍历,而every方法也会停止遍历并直接返回false。\[3\] 总结起来,some方法用于判断数组中是否存在满足条件的元素,而every方法用于判断数组中的所有元素是否都满足条件。 #### 引用[.reference_title] - *1* *3* [JS 数组方法 every 和 some 的区别](https://blog.csdn.net/linyichao123/article/details/128229897)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [js中some和every用法](https://blog.csdn.net/qq_41328247/article/details/130930506)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值