如何使用数组值评估“全有或全无条件”

问题描述

我有一个包含用户信息值(例如姓名、联系人和地址)的表单。地址有效性的逻辑是“全有或全无”条件——这意味着如果用户没有为地址输入输入任何值,那么它是有效的,但如果他们输入一个地址输入(即街道名称)但缺少其他东西(即邮政)则无效。

表单数据的结构如下:

form: {
   first_name: {
      value: ‘’,valid: false,},last_name: {
      value: ‘’,//... more values here
   street: {
      value: ‘’,city: {
      value: ‘’,state: {
      value: ‘’,postal: {
      value: ‘’,country: {
      value: ‘’,}

以下是用于测试该逻辑的代码,如果streetcitystatepostalcountry都为空,那么一切都是有效的。但是如果其中一个被赋予了值,那么其余的也必须被提供

const addressKeys = ['street','city','state','postal','country']
let isAddValid = form[addressKeys.pop()].value !== ''

for(const key of addressKeys) {
    isAddValid = !(isAddValid ^ form[key].value === ''))
}

console.log('is address valid?',isAddValid)

这将正确返回有效值(当输入所有值时,如果至少提供一个值时缺少一个或多个值),但它没有正确评估所有空值(未提供输入值)是否有效。我错过了什么?

解决方法

您可以使用 .every() 来检查 addressKeys 中的所有键是否为空,或者 (||) 都为非空。

const form = { first_name: { value: '',valid: false,},last_name: { value: '',street: { value: '',city: { value: '',state: { value: '',postal: { value: '',country: { value: '',};

const addressKeys = ['street','city','state','postal','country'];
const valid = addressKeys.every(key => form[key].value === '') || addressKeys.every(key => form[key].value !== '');
console.log(valid);

这乍一看似乎效率低下,但此代码在 .every() 方法调用和 || 操作中都会短路。这意味着如果所有值实际上都是空的,则无需检查它们是否都包含值,由于 || 的工作原理,JS 将为我们跳过数组的额外迭代。类似地,如果除 state 之外的所有对象都包含空值,则第一个 .every() 调用将在发现 state 非空后立即停止,并且不会检查任何进一步的值,因为它已经知道它没有通过测试。然后当第二个 .every() 调用进行检查时,它会立即看到 street 包含一个空值,并且也会短路,立即返回 false 而无需遍历整个数组。

,

我认为 for 循环中的 xor 不正确,也许应该这样做:

function check(form) {
    const addressKeys = ['street','country'];
    let isAddValid = form[addressKeys.pop()].value !== '';
    // check others,if others is different from isAddVaild; return false;
    for(const key of addressKeys) {
        if (isAddValid ^ form[key].value !== '') {
            return false;
        }
    }
    return true;
}


console.log('is address valid?',check(form))