Javascript:确定数组中的所有元素是否是对象中的键

时间:2014-09-01 00:31:49

标签: javascript arrays object for-loop

我试图弄清楚数组中的所有元素是否都是对象中的键。

var obj = { name: 'Computer', cost: '$1,000' };
var myArray = [ 'name', 'cost', 'bio' ]; //another example would be var myArray = [];
for(var x = 0; x < myArray.length; x++){
if (myArray[x] in obj)
  {
     return true;
  }
}

如何检查数组中的所有元素是否都是对象中的键?

5 个答案:

答案 0 :(得分:3)

反过来做。如果您发现数组中的某个人不在该对象中,那么您将返回false。如果到达循环的末尾,则返回true,因为所有键都在对象中。

答案 1 :(得分:2)

根据您的需要,这可能会有所帮助:

function hasKeys(obj, keys) {
    for (var i=0; i != keys.length; ++i) {
        if (!(keys[i] in obj))
            return false;
    }
    return true;
};

你需要问自己一个微妙之处:你想知道对象是否直接拥有密钥(即不是原型堆栈中的某个地方?)如果是,那么用keys[i] in obj替换obj.hasOwnProperty(keys[i]) < / p>

答案 2 :(得分:1)

function hasKeys(obj, keys) {
    return keys.every(Object.prototype.hasOwnProperty.bind(obj));
}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every状态,&#34;每个方法对数组中存在的每个元素执行一次提供的回调函数,直到找到一个回调返回伪值的值(转换为a时变为false的值)布尔)。 如果找到这样的元素,则every方法立即返回false。否则,如果callback为所有元素返回true值,则每个方法都返回true。仅为已分配值的数组的索引调用回调;对于已删除或从未分配过值的索引,不会调用它。 (强调我的)。

答案 3 :(得分:0)

Array.some()提供了一个干净的解决方案。

// object in question
var obj = { ... };

// keys that need to be present in the object
var keys = [ ... ];

// iterate through the whitelist until we find a key that doesn't exist in the object. If all exist, that means Array.some() is false.
var valid = !keys.some(function(key) {
    return !obj.hasOwnProperty(key);
});

另一种解决方案是使用类似的概念,但使用Array.every()。需要注意的是,这通常会较慢,因为它总是需要触摸白名单中的每个元素。

// iterate through the whitelist, making sure the object has each key.
var valid = keys.every(obj.hasOwnProperty);

答案 4 :(得分:0)

这个问题可以用集合包含来表达:属性集的集合是否完全包含所需键的数组?所以我们可以把它写成

includes(Object.keys(obj), arr)

所以现在我们只需要写includes

function includes(arr1, arr2) {
    return arr2.every(function(key) {
        return contains(arr1, key);
    }
}

对于contains,我们可以使用Underscore的_.contains,或者只是自己编写:

function contains(arr, val) {
    return arr.indexOf(val) !== -1;
}

如果我们对可读性的可能性感兴趣,我们可以将includes的定义缩短为使用Function#bind而不是匿名函数:

function includes(arr1, arr2) {
    return arr2.every(contains.bind(0, arr1));
}

现在我们有了可以用于其他事情的函数,而不是混淆问题的两个不同方面 - 对象的键和集合包含。如果我们真的想要编写一个多功能一体的功能,它就会变得更具可读性:

function hasMany(obj, arr) {
    return arr.every(_.contains.bind(0, Object.keys(obj));
}

如果我们想要更多的可读性,就像我们写一本小说一样:

function object_has_required_keys(object, required_keys) {

    var object_keys = Object.keys(object);

    function key_is_present(key) {
        return object_keys.indexOf(key) !== -1;
    }

    return required_keys.every(key_is_present);
}

下划线的_.intersection

如果我们懒惰(或聪明),我们可以使用下划线的_.intersection来实施includes

function includes(arr1, arr2) {
    return _.intersection(arr1, arr2).length === arr2.length;
}

想法是取交点,如果第一个数组完全包含第二个数组,那么交集将包含第二个数组的所有元素,我们可以通过比较它们的长度来检查。

使用ES6设置

提前考虑ES6,我们可以使用sets来实现include,这应该更快:

function includes(arr1, arr2) {
    var set = new Set(arr1);
    return arr2.every(Set.prototype.has.bind(set));
}