使用两个for循环和if(k in obj)迭代一个对象

时间:2015-05-28 06:32:46

标签: javascript loops

我需要遍历两个对象并检查它们的键是否匹配。诀窍是,我需要确保键都是小写的。我发布了here

如果我只是遍历两个对象并检查匹配,那么这很容易完成。但这意味着我可能最坏的运行时间直到每个对象的最后一个键。

我把一个计数器放在上面,最后得到了大量的支票:

var i = 0;

for (key in objA) {
    for (key2 in objB) {
    i++; //ends up at 185 checks
    if (key.toLowerCase() === key2.toLowerCase()) {
          console.log('match');

我不确定if (k in..)语法的性能差异,因为我无法通过内循环进行迭代。

for (key in objA) {
     if (key in objB) {
     //i = ?

这两者之间的性能差异是什么?

注意:对象的长度不匹配。基本上,我传递一个较小的对象,其中包含我需要检查较大对象的键。出于我的项目的目的,我需要检查较小对象中的任何键是否在较大的对象中。

我检查了开始和结束之间的日期时间差异。

var start = (new Date).getTime();

//loop

var diff = (new Date).getTime() - start;

循环1:4秒

循环2:1秒

问题是,我需要一些方法来使用更有效的if (k in obj)检查来有效地检查来自不同大小的对象的两个小写密钥。

3 个答案:

答案 0 :(得分:0)

首先,您可能想要检查两个对象是否具有相同数量的密钥:

Object.keys(objA).length === Object.keys(objB).length;

如果这些长度不匹配,则对象没有相同的键。

现在,如果这些长度 匹配,您可以使用第二个代码段来比较密钥,这意味着您只需迭代n个密钥,而不是n * n ,就像你在你的第一个片段中那样。

请记住,这些检查区分大小写。

这样的事情应该有效:

function checkKeys(objA, objB){
    if(Object.keys(objA).length !== Object.keys(objB).length)
        return false;
    for (key in objA) {
        if (!(key in objB))
            return false;
    }
    return true;
};

alert(checkKeys({}, {}));
alert(checkKeys({}, {a: 1}));
alert(checkKeys({a: 1}, {a: 1}));
alert(checkKeys({a: 1}, {A: 1}));
alert(checkKeys({a: 1}, {a: 1, b: 2}));

答案 1 :(得分:0)

如何检查他们是否拥有hasOwnProperty的该属性?

for (key in objA) {

    if (objB.hasOwnProperty(key)))
        console.log("HAS the property/key, do something");
    }
    else {
        console.log("Doesn't have the property/key, do something");    
    }
}

如果只有一个键具有较低的键,则检查小写的最简单方法

key = key.toLowerCase(); // before the objB check

或者在此操作之前,您可以像Jack一样在此检查之前将其转换为小写:

var key, keys = Object.keys(obj);
var n = keys.length;
var newobj={}
while (n--) {
    key = keys[n];
    newobj[key.toLowerCase()] = obj[key];
}

What's the best way (most efficient) to turn all the keys of an object to lower case?

答案 2 :(得分:0)

如果一个对象相当大,您可以先转换该对象的键,然后针对它测试较小的对象:

function test(big, small)
{
  // lowercase all keys in the bigger object
  var map = {};
  for (var bk in big) {
    map[bk.toLowerCase()] = true;
  }

  // test all keys in smaller object against map
  for (var sk in small) {
    if (!(sk.toLowerCase() in map)) {
      return false;
    }
  }
  return true;
}

或者这种奇特的方式:

function test(big, small)
{
  var map = Object.keys(big).reduce(function(map, key) {
    map[key.toLowerCase()] = true;
    return map;
  }, {});

  return Object.keys(small).all(function(key) {
    return key.toLowerCase() in map;
  });
}