有效地查找数组中对象的索引

时间:2016-04-29 20:24:54

标签: javascript jquery json

我试图找到数组中对象的索引。我知道有一种方法可以用underscore.js来做到这一点,但我试图找到一种没有underscore.js的有效方法。这就是我所拥有的:

var arrayOfObjs = [{
  "ob1": "test1"
}, {
  "ob2": "test1"
}, {
  "ob1": "test3"
}];

function FindIndex(key) {
  var rx = /\{.*?\}/;            // regex: finds string that starts with { and ends with }
  var arr = [];                  // creates new array
  var str = JSON.stringify(arrayOfObjs);          // turns array of objects into a string
  for (i = 0; i < arrayOfObjs.length; i++) {      // loops through array of objects
    arr.push(str.match(rx)[0]);                   // pushes matched string into new array
    str = str.replace(rx, '');                    // removes matched string from str
  }
  var Index = arr.indexOf(JSON.stringify(key));   // stringfy key and finds index of key in the new array
  alert(Index);
}

FindIndex({"ob2": "test1"});

JSFIDDLE

这有效,但我担心它不是很有效率。任何替代方案?

6 个答案:

答案 0 :(得分:7)

这是一种方法,使用some()稍微可靠且效率更高,并在对象不匹配时立即停止等。

var arrayOfObjs = [{
  "ob1": "test1"
}, {
  "ob2": "test1"
}, {
  "ob1": "test3"
}];

function FindIndex(key) {
    var index = -1;

    arrayOfObjs.some(function(item, i) {
    	var result = Object.keys(key).some(function(oKey) {
            return (oKey in item && item[oKey] === key[oKey]);
        });
        if (result) index = i;
        return result;
    });
    
    return index;
}

var index = FindIndex({"ob2": "test1"});

document.body.innerHTML = "'{\"ob2\": \"test1\"}' is at index : " + index;

答案 1 :(得分:6)

带有访问示例的哈希表。

&#13;
&#13;
var arrayOfObjs = [{ "obj1": "test1" }, { "obj2": "test1" }, { "obj1": "test3" }],
    hash = {};

arrayOfObjs.forEach(function (a, i) {
    Object.keys(a).forEach(function (k) {
        hash[k] = hash[k] || {};
        hash[k][a[k]] = i;
    });
});

document.write('<pre>' + JSON.stringify(hash['obj2']['test1'], 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(hash, 0, 4) + '</pre>');
&#13;
&#13;
&#13;

答案 2 :(得分:5)

执行此操作的一种方法是使用every查看“过滤器”中的每个键是否在对象中具有匹配的正确值。 every确保循环在找到不匹配或缺失值时立即停止。

function log(msg) {
  document.querySelector('pre').innerHTML += msg + '\n';
}

var arr = [
  {
    a: 1
  },
  {
    b: 2
  },
  {
    c: 3,
    d: 4
  },
  {
    a: 1 // Will never reach this since it finds the first occurrence
  }
];

function getIndex(filter) {
  var keys = Object.keys(filter);
  for (var i = 0, len = arr.length; i < len; i++) {
    var obj = arr[i];
    var match = keys.every(function(key) {
      return filter[key] === obj[key];
    });
    if (match) {
      return i;
    }
  }
  
  return -1;
}

log(getIndex({ a: 1 }));
log(getIndex({ b: 2 }));
log(getIndex({ c: 3 }));
log(getIndex({ c: 3, d: 4 }));
log(getIndex({ e: 5 })); // Doesn't exist, won't find it
<pre></pre>

答案 3 :(得分:1)

作为您自定义构建方法的替代方案,lodash's findIndex method会为您完成此操作:

var arrayOfObjs = [{
  "ob1": "test1"
}, {
  "ob2": "test1"
}, {
  "ob1": "test3"
}];

_.findIndex(arrayOfObjs, {"ob2": "test1"}); // => 1

答案 4 :(得分:1)

由于两个不同对象上的测试相等性总是返回false,因此您可以首先测试键然后测试值,

使用reduce:

&#13;
&#13;
if(container[middle]<search)
&#13;
&#13;
&#13;

答案 5 :(得分:1)

findIndex在旧浏览器中无法使用,但专为此目的而设计。

&#13;
&#13;
var arrayOfObjs = [{
  "ob1": "test1"
}, {
  "ob2": "test1"
}, {
  "ob1": "test3"
}];

function FindIndex(key) {
  return arrayOfObjs.findIndex(
    obj => Object.keys(key).every(name => key[name] === obj[name])
  );
}

alert(FindIndex({"ob2": "test1"})); // 1
&#13;
&#13;
&#13;