【问题标题】:Search JS Object for Value在 JS 对象中搜索值
【发布时间】:2011-11-26 01:12:50
【问题描述】:

假设我有一个对象:

userInfo

我想搜索 userInfo 的每个节点,看看键 'username' 的值是否等于 foo。

userInfo[x].username == "foo" 

有没有更好的方法来做以下事情?

var matchFound = false;

for (var i = 0, len = userInfo.length; i < len; i++)
     matchFound = userInfo[i].username == "foo";

【问题讨论】:

  • 这行不通。 matchFound 的值不断被覆盖。
  • 另外,? true : false 部分的意义何在? userInfo[i].username == "foo" 已经评估为真或假。
  • 从技术上讲,您正在循环通过 Array,其中包含 Objects。没有太多更好的 方法可以做到这一点。 @awm,我假设他向我们展示了伪代码。
  • 我解决了这个问题。我只是很快就把这个例子放在一起。问题更多是关于如何搜索对象以及是否有更好的方法。

标签: javascript loops javascript-objects


【解决方案1】:

如果不引入另一种数据结构,真的没有更好(更有效)的方法。答案实际上取决于您的使用情况,但您可以做一些不同的事情:

  1. 使用哈希创建单独的“索引”。这些结构会将键映射到源数组中的项目或索引。 JavaScript 对象/哈希支持基于键的查找并且应该是高效的。

    userinfo[x].username = "foo";
    // Index the objects
    usersByName = {};
    usersByName["foo"] = userinfo[x];
    // -- OR -- index the array indices
    var usersByName["foo"] = x;
    // Test for key
    "foo" in usersByName; // true
    

    您必须做更多的工作来保持索引和源数组之间的一致性。最好将两者都包装在另一个对象中以管理两者的内容。如果您要查找对象的多个字段,这种方法很好。

  2. 如果您不关心集合的顺序,您可以将整个内容更改为哈希并按用户名索引

    var userinfo = {};
    userinfo["foo"] = {username: "foo", firstName: "Foo", lastName: "Bar"};
    

不过,需要考虑的一件事是,效率提升是否会超过维护索引所增加的代码复杂性。如果您没有进行大量搜索,并且 userinfo 集合中没有大量项目,那么编写一个通用搜索函数或使用 Philip Schweiger 提到的库可能更有意义。

function findObjectByAttribute (items, attribute, value) {
  for (var i = 0; i < items.length; i++) {
    if (items[i][attribute] === value) {
      return items[i];
    }
  }
  return null;
}
var userinfo = [];
userinfo[0] = {username: "foo"};
console.log(findObjectByAttribute(userinfo, "username", "foo"));

【讨论】:

    【解决方案2】:

    下划线 JS 库有一些方便的方法来处理数据集合 - 例如,select method

    实现它就像这样:

    var userInfo = {
        'x':{
            username: "foo",
            password:'dlji'
        },
        'y':{
            username: "bar" ,
            password:'adfasf'
        },
        'z': {
            username: 'foo',
            password:'d3alj4i'
        }
    };
    
    var found = _.select(userInfo, function(node){
    
        return node.username === "foo"
    }); 
    console.dir (found);
    

    下划线不是很大,虽然您也可以在本机 JS 中执行此操作,但我认为它可以很好地实现您自己提出的解决方案。基本上,它为您提供了许多您认为无论如何都应该存在的 JS 功能。

    【讨论】:

      【解决方案3】:

      不需要三元运算符,考虑以下:

      var matchFound = false;
      
      for (var i = 0, len = userInfo.length; i < len; i++)
      {
          matchFound = userInfo[i].username == "foo";
          if(matchFound){
              break;
          }
      }  
      

      【讨论】:

      • 嗯,没错,但我的问题的本质更多是关于找到一种更有效的搜索对象的方法(如果存在的话)。
      猜你喜欢
      • 2012-01-20
      • 1970-01-01
      • 2023-02-21
      • 2021-08-21
      • 2018-05-05
      • 1970-01-01
      • 2015-07-30
      • 2015-12-10
      • 1970-01-01
      相关资源
      最近更新 更多