【问题标题】:how to check if all object keys has false values如何检查所有对象键是否具有错误值
【发布时间】:2014-06-29 13:29:11
【问题描述】:

JS 对象:

var saver = {
        title: false,
        preview: false,
        body: false,
        bottom: false,
        locale: false
};

问题是如何检查所有值是否为false

我可以使用 $.each() jQuery 函数和一些标志变量,但可能有更好的解决方案?

【问题讨论】:

  • 你的意思是没有遍历属性?
  • 是的。我想找到更优雅的解决方案。
  • 下面添加了一个更优雅的解决方案。 无需迭代,只需使用 jQuery 即可。

标签: javascript jquery arrays javascript-objects


【解决方案1】:

更新版本。感谢@BOB 指出您可以直接使用values

Object.values(obj).every((v) => v === false)

此外,如果对象值是falsy(例如0, undefined, null, false),则要求与false 比较的问题和下面的大多数答案返回true,而不仅仅是它们严格为假.


这是一个非常简单的解决方案,需要 JavaScript 1.8.5。

Object.keys(obj).every((k) => !obj[k])

例子:

obj = {'a': true, 'b': true}
Object.keys(obj).every((k) => !obj[k]) // returns false

obj = {'a': false, 'b': true}
Object.keys(obj).every((k) => !obj[k]) // returns false

obj = {'a': false, 'b': false}
Object.keys(obj).every((k) => !obj[k]) // returns true

你也可以写

Object.keys(obj).every((k) => obj[k] == false)
Object.keys(obj).every((k) => obj[k] === false)  // or this
Object.keys(obj).every((k) => obj[k])  // or this to return true if all values are true

有关详细信息,请参阅Mozilla Developer Network Object.keys()'s reference

【讨论】:

  • Object.values(obj).every((value) => value === false) 也应该可以工作。
【解决方案2】:

这样就可以了...

var result = true;

for (var i in saver) {
    if (saver[i] === true) {
        result = false;
        break;
    }
}

您可以通过索引或键(如上)使用循环来迭代对象。

如果你追求整洁的代码,而不是重复,那么只需将它放在一个函数中......

Object.prototype.allFalse = function() { 
    for (var i in this) {
        if (this[i] === true) return false;
    }
    return true;
}

然后你可以在需要的时候调用它,像这样......

alert(saver.allFalse());

这是一个工作示例...

Object.prototype.allFalse = function() { 
    for (var i in this) {
        if (this[i] === true) return false;
    }
    return true;
}

var saver = {
        title: false,
        preview: false,
        body: false,
        bottom: false,
        locale: false
};

console.log("all are false - should alert 'true'");
console.log(saver.allFalse());

saver.body = true;

console.log("one is now true - should alert 'false'");
console.log(saver.allFalse());

【讨论】:

  • 谢谢。但是这个方法和我的 $.each() 方法很相似。我的问题是如何避免迭代?
  • 你无法避免迭代。如果有一种本地方式来做你所要求的,它将涉及在后台进行迭代。我认为你能期望的最好的结果是一个小的或整洁的迭代。
  • 你不能。并且迭代效率更高,否则如果您更改了对象的属性,您将不得不更改检查它们的代码。
  • 只是稍微改变了它以适应特定的“所有属性都是假的”,而不是我最初采用的“是否存在真的”方法。
  • 好的,谢谢。看起来除了迭代没有其他方法。哦,好吧...... =)但我肯定会使用你关于功能的最后一句话。
【解决方案3】:

在评论中,您询问是否可以避免迭代。如果您使用支持函数式方法的 javascript 库,例如 UnderscoreLodashSugar,则可以。

使用 Underscore 和 Lodash,您可以编写如下内容:

var result = _.every(_.values(saver), function(v) {return !v;});

使用 Sugar,您可以简单地编写:

var result = Object.all(saver,false);

【讨论】:

  • 你也可以在 Lodash 中这样做:var result = _.every(_.valuesIn(saver), Boolean));
  • 洛达什:const result = _.some(saver);
【解决方案4】:

使用array.some()

它更干净易懂!而且它可以节省我们的运行时间,因为一旦函数条件存在一次,它就会跳出循环并返回true。

Object.values(obj).some(val => val)

如果你真的需要严格相等来写这个:

Object.values(obj).some(val => val !== false)

Object.values(obj) 用每个键的值创建一个数组。

【讨论】:

    【解决方案5】:

    短而方便的单行,浏览器完全支持:

    Object.keys(saver).every(k => saver[k] === false);
    

    Object.values(saver).every(v => v === false);
    

    (小心,Object.values() 尚不被 IE 支持。)

    【讨论】:

      【解决方案6】:

      这应该适用于所有主要浏览器:

      Object.keys(saver).every(key => saver[key] === false); // return true
      

      【讨论】:

        【解决方案7】:

        这样做,

         for (var i in saver) {
          if (saver[i]) {
            return false; // here if any value is true it wll return as false /
          }
         }
         return true; //here if all value is false it wll return as true
        

        【讨论】:

          【解决方案8】:

          如果您想不进行外部迭代(即在您的代码中),请尝试使用$.map 将属性映射到数组,然后使用$.inArray 来查看是否存在任何真值:

          var allFalse = $.inArray(true, $.map(saver, function(obj){return obj})) < 0;
          

          JSFiddle:http://jsfiddle.net/TrueBlueAussie/FLhZL/1/

          【讨论】:

            【解决方案9】:

            你也可以使用 lodash const allFalse = !_.some(saver);

            【讨论】:

            • 他们想知道是否所有的都是假的(不是真的)。所以,如果有些是真的,那么并不是所有的都是假的。
            【解决方案10】:

            Lodash (3.10.1+) 使这更清晰地表达:

            _.every({a: false, b: false, c: false}, _.negate(Boolean)); // True
            

            但在ngstschr's answer 中使用_.some 更简洁。

            【讨论】:

              【解决方案11】:

              ✏️ 这个单行代码检查对象数组的任何对象内是否存在虚假值:

              const hasFalsyValue = (list) =>
               !list.every(obj => Object.values(obj).every(prop => prop))
              

              我发现这对于防止 null / falsy 值被进一步传递很有用:

              const listA = [ { a:'?', b:100 }, { a:'?', b:200 } ]
              
              const listB = [ { a:null, b:100 }, { a:'?', b:200 } ]
              
              // hasFalsyValue(listA) === false
              // hasFalsyValue(listB) === true
              

              只有一个细节我们应该注意:

              ⚠️ 在 Javascript 中 0'' 是 Falsy 值! ⚠️

              因此,如果 hasFalsyValue() 在数组中的对象内找到任何零值或任何空字符串值,它将认为它是假值并因此返回 true!

              ...虽然这可能是您想要的,但有时您可能希望允许将任何特定的 Falsy 值视为 Truthy。

              ✍? 假设您想在您的对象中允许零值,您可以执行以下操作:

              const hasFalsyValue_ZeroAllowed =
               (list) => !list.every(obj => Object.values(obj).every(prop =>  prop || prop === 0))
              
              

              现在零值不再被认为是虚假的:

              
              const listC = [ { a:0, b:100 }, { a:'?', b:200 } ]
              const listD = [ { a: null, b:100 }, { a:'?', b:200 } ]
              
              hasFalsyValue_ZeroAllowed(listC) // false
              hasFalsyValue_ZeroAllowed(listD) // true
              
              

              您可以继续向函数添加更多条件以进行定制验证:

              ✍? 允许空值:

              const hasFalsyValue_NullAllowed =
               (list) => !list.every(obj => Object.values(obj).every(prop =>  prop || prop === null))
              
              const listE = [ { a: null, b:100 }, { a:'?', b:200 } ]
              
              hasFalsyValue_NullAllowed(listE) // false
              
              

              ✍? 允许空字符串值:

              const hasFalsyValue_EmptyStringAllowed =
               (list) => !list.every(obj => Object.values(obj).every(prop =>  prop || prop === ''))
              
              const listF = [ { a: '', b:100 }, { a:'?', b:200 } ]
              
              hasFalsyValue_EmptyStringAllowed(listF)  // false
              

              【讨论】:

                【解决方案12】:

                从 Lodash 4.0 开始,可以使用overEvery

                overEvery(saver, false) 循环遍历每个元素并检查其是否为 false

                如果每个元素都是false,则返回true,否则返回false

                【讨论】:

                • 我无法弄清楚 ES6 (Angular) 的语法。它返回一个函数,我需要它返回一个布尔值。
                • @tatsu 发布一个包含更多详细信息的新问题
                • 这是不正确的,overEvery 返回一个函数。每个文档:“创建一个函数,该函数在使用它接收的参数调用时检查所有谓词是否返回真值。”
                猜你喜欢
                • 2019-09-21
                • 2019-12-15
                • 1970-01-01
                • 2020-05-12
                • 2012-06-05
                • 2021-12-10
                • 1970-01-01
                • 1970-01-01
                • 2021-09-05
                相关资源
                最近更新 更多