如何在没有for循环的情况下从对象获取键和值?

时间:2012-06-06 18:42:26

标签: coffeescript

是否有更好的方法来获取对象的键和值?我试图在没有for循环的情况下这样做。

obj = { collection: 'foo' }

for key, value of obj
  console.log key, value

如果一个对象有一个具有一个值的键,我认为可以采用更有效的方法。我可能错了。

1 个答案:

答案 0 :(得分:2)

如果您只想检查对象是否只有一个密钥,那么您可以使用短路循环:

exactly_one = (obj) ->
    return false if(!obj)
    how_many = 0
    for own key of obj
        break if(++how_many == 2)
    how_many == 1

基本思想是使用for ... of(即JavaScript的for ... in)循环来开始计算对象中的键数。我们关心的案例只有三个:

  1. 密钥少于一个(即null或没有密钥)。最初的null检查和how_many = 0初始化会解决此问题。
  2. 只有一把钥匙。在这种情况下,循环将进行一次传递,++how_many将在离开how_many == 1后被点击。
  3. 有多个键。在这种情况下,循环将仅由break进行两次迭代。我们知道,一旦遇到第二个密钥,我们就会得到false结果,因此无需继续计算。
  4. 这将使函数最多进行两次循环迭代。这仍然是一个循环,但没有规则强制你在不需要的时候运行整个循环,你可以尽早break出来。

    演示:http://jsfiddle.net/ambiguous/qsNMA/

    对逻辑的微小调整会给你“至多一个”,“至少一个”等等。

    如果你不是C编程员,那么你可以稍微展开逻辑:

    for own key of obj
        ++how_many
        break if(how_many == 2)
    

    你也可以把它写成:

    (break if(++how_many == 2)) for own key of obj
    

    但是这推动了IMO。

    own内容只会添加hasOwnProperty项检查,以避免意外地从原型中抓取内容。你可能不需要这样,但因为他们真的想要帮我,所以我更倾向于谨慎。

    还有Object.keys,但这并不是普遍支持的,当你只关心它的长度是否为1时,它必须构建一个完整的数组:

    exactly_one = (obj) ->
        return false if(!obj)
        Object.keys(obj).length == 1
    

    演示:http://jsfiddle.net/ambiguous/aH8wA/