【问题标题】:How to find a value in an array of objects in JavaScript?如何在 JavaScript 中的对象数组中查找值?
【发布时间】:2011-07-08 01:53:42
【问题描述】:

我有一个对象数组:

Object = {
   1 : { name : bob , dinner : pizza },
   2 : { name : john , dinner : sushi },
   3 : { name : larry, dinner : hummus }
}

我希望能够在对象/数组中搜索键为“dinner”的位置,并查看它是否与“sushi”匹配。

我知道 jQuery 有 $.inArray,但它似乎不适用于对象数组。或者也许我错了。 indexOf 似乎也只适用于一个数组级别。

是否没有此功能或现有代码?

【问题讨论】:

  • 这已经被问过了。您必须编写自己的函数或使用其他库。
  • 请注意Object在Javascript中是保留的,Object是object对象,即所有对象之母。
  • 问题和接受的答案与多维数组无关,而更多地与通过其项目的属性值过滤的一维数组有关。 => 他们没有解决我的问题“在多维数组中查找值”。

标签: javascript jquery arrays search


【解决方案1】:

如果你有一个数组比如

var people = [
  { "name": "bob", "dinner": "pizza" },
  { "name": "john", "dinner": "sushi" },
  { "name": "larry", "dinner": "hummus" }
];

您可以使用数组对象的filter 方法:

people.filter(function (person) { return person.dinner == "sushi" });
  // => [{ "name": "john", "dinner": "sushi" }]

在较新的 JavaScript 实现中,您可以使用函数表达式:

people.filter(p => p.dinner == "sushi")
  // => [{ "name": "john", "dinner": "sushi" }]

您可以使用map 搜索拥有"dinner": "sushi" 的人

people.map(function (person) {
  if (person.dinner == "sushi") {
    return person
  } else {
    return null
  }
}); // => [null, { "name": "john", "dinner": "sushi" }, null]

reduce

people.reduce(function (sushiPeople, person) {
  if (person.dinner == "sushi") {
    return sushiPeople.concat(person);
  } else {
    return sushiPeople
  }
}, []); // => [{ "name": "john", "dinner": "sushi" }]

我相信您可以将其推广到任意键和值!

【讨论】:

  • 请记住,这些解决方案是 ECMAScript 5 的一部分,在 IE8 中不受支持。 kangax.github.com/es5-compat-table 尽管我更喜欢 @adamse 的回答,但亚历克斯的回答对“旧的垃圾浏览器”更友好。但不确定性能。
  • @SalmanA - 问题或解决方案都不是指 jQuery。使用了 javascript filter(),而不是 jQuery 特定的 $.filter() - tutorialspoint.com/javascript/array_filter.htm
  • 如EasyCo所说,IE8不支持过滤功能。但是,它很容易添加到 Array 原型中,因此可以在脚本开头带有小功能的任何浏览器中使用。这在filter documentation 中有概述。它给出了 ECMA-262 中指定的确切功能,所以实际上是一样的。
  • 我刚刚添加了an answer,它使用了jQuery的grep方法。将您的答案作为与您正在做的事情相同的概念可能是有意义的,但是依赖于 jQuery 并且对浏览器友好。
  • 我的返回变量是否不断出现引用错误?我尝试了返回“x”的前两个答案,它一直说它是未定义的......
【解决方案2】:

jQuery 有一个内置方法 jQuery.grep,其工作方式类似于来自 @adamse's Answer 的 ES5 filter 函数,并且应该在旧版浏览器上运行良好。

以亚当斯为例:

var peoples = [
  { "name": "bob", "dinner": "pizza" },
  { "name": "john", "dinner": "sushi" },
  { "name": "larry", "dinner": "hummus" }
];

您可以执行以下操作

jQuery.grep(peoples, function (person) { return person.dinner == "sushi" });
  // => [{ "name": "john", "dinner": "sushi" }]

【讨论】:

    【解决方案3】:
    var getKeyByDinner = function(obj, dinner) {
        var returnKey = -1;
    
        $.each(obj, function(key, info) {
            if (info.dinner == dinner) {
               returnKey = key;
               return false; 
            };   
        });
    
        return returnKey;       
    
    }
    

    jsFiddle.

    只要-1 永远不是有效的密钥。

    【讨论】:

    • 差一点点赞了这个,但帖子里没有解释。
    【解决方案4】:

    如果您要经常进行此搜索,请考虑更改对象的格式,以便晚餐实际上是关键。这有点像在数据库表中分配主聚集键。所以,例如:

    Obj = { 'pizza' : { 'name' : 'bob' }, 'sushi' : { 'name' : 'john' } }
    

    您现在可以像这样轻松访问它:Object['sushi']['name']

    或者如果对象真的这么简单(只是对象中的“名称”),您可以将其更改为:

    Obj = { 'pizza' : 'bob', 'sushi' : 'john' }
    

    然后像这样访问它:Object['sushi']

    显然,像这样重构数据对象并不总是可能或对您有利,但关键是,有时最好的答案是考虑您的数据对象是否以最佳方式构建。像这样创建密钥可以更快并创建更简洁的代码。

    【讨论】:

    • 爱你回答,但我发现语法有问题:我的工作方式是这样的:obj = { "pizza" : { "name" : "bob" }, "sushi" : { "name" : "约翰" } } 警报 (obj['pizza']['name']);但仍然。谢谢!找到了我正在寻找的东西! )
    • @alexela 感谢 alexela!我用你的敏锐观察更新了我的答案!我刚刚复制了 OP 帖子中的示例并忽略了添加引号,但你是对的 - 除非至少在值周围有引号(假设它们是值而不是变量),否则它将不起作用。
    【解决方案5】:

    您可以使用Alasql library 在数组中找到对象:

    var data = [ { name : "bob" , dinner : "pizza" }, { name : "john" , dinner : "sushi" },
         { name : "larry", dinner : "hummus" } ];
    
    var res = alasql('SELECT * FROM ? WHERE dinner="sushi"',[data]);
    

    试试这个例子in jsFiddle

    【讨论】:

    • 我不确定这是否真的应该被否决。当需求变得比单个过滤器或减少调用更复杂时,对集合的类似 Sql 的查询变得更容易推理和编写。 Alasql 是一个非常令人印象深刻的库,但对于上面的示例来说确实有点矫枉过正。
    • 如果对象本身来自 SQL 源,那么这个答案简直是天才。
    【解决方案6】:

    您可以使用简单的 for in 循环:

    for (prop in Obj){
        if (Obj[prop]['dinner'] === 'sushi'){
    
            // Do stuff with found object. E.g. put it into an array:
            arrFoo.push(Obj[prop]);
        }
    }
    

    以下小提琴示例将所有包含dinner:sushi 的对象放入一个数组中:

    https://jsfiddle.net/3asvkLn6/1/

    【讨论】:

      【解决方案7】:

      这里已经有很多很好的答案了,为什么不多一个,使用像 lodash 或 underscore 之类的库:)

      obj = {
         1 : { name : 'bob' , dinner : 'pizza' },
         2 : { name : 'john' , dinner : 'sushi' },
         3 : { name : 'larry', dinner : 'hummus' }
      }
      
      _.where(obj, {dinner: 'pizza'})
      >> [{"name":"bob","dinner":"pizza"}]
      

      【讨论】:

        【解决方案8】:

        我必须在嵌套站点地图结构中搜索与给定路径匹配的第一个叶项。我使用.map() .filter().reduce 想出了以下代码。返回找到的与路径 /c 匹配的最后一项。

        var sitemap = {
          nodes: [
            {
              items: [{ path: "/a" }, { path: "/b" }]
            },
            {
              items: [{ path: "/c" }, { path: "/d" }]
            },
            {
              items: [{ path: "/c" }, { path: "/d" }]
            }
          ]
        };
        
        const item = sitemap.nodes
          .map(n => n.items.filter(i => i.path === "/c"))
          .reduce((last, now) => last.concat(now))
          .reduce((last, now) => now);
        

        【讨论】:

          【解决方案9】:

          如果您想通过搜索功能查找特定对象,请尝试以下操作:

              function findArray(value){
          
                  let countLayer = dataLayer.length;
                  for(var x = 0 ; x < countLayer ; x++){
          
                      if(dataLayer[x].user){
                          let newArr = dataLayer[x].user;
                          let data = newArr[value];
                          return data;
                      }
          
                  }
          
                  return null;
          
              }
          
              findArray("id");
          

          这是一个示例对象:

          layerObj = {
              0: { gtm.start :1232542, event: "gtm.js"},
              1: { event: "gtm.dom", gtm.uniqueEventId: 52},
              2: { visitor id: "abcdef2345"},
              3: { user: { id: "29857239", verified: "Null", user_profile: "Personal", billing_subscription: "True", partners_user: "adobe"}
          }
          

          代码将迭代并找到“用户”数组,并搜索您在其中寻找的对象。

          我的问题是数组索引在每次窗口刷新时都会更改,并且它在第三个或第二个数组中,但这并不重要。

          对我来说就像一个魅力!

          在你的例子中它有点短:

          function findArray(value){
          
              let countLayer = Object.length;
              for(var x = 0 ; x < countLayer ; x++){
          
                  if(Object[x].dinner === value){
                      return Object[x];
                  }
          
              }
          
              return null;
          
          }
          
          findArray('sushi');
          

          【讨论】:

            【解决方案10】:

            我们使用object-scan 进行大部分数据处理。它在概念上非常简单,但允许很多很酷的东西。以下是您解决问题的方法

            // const objectScan = require('object-scan');
            
            const findDinner = (dinner, data) => objectScan(['*'], {
              abort: true,
              rtn: 'value',
              filterFn: ({ value }) => value.dinner === dinner
            })(data);
            
            const data = { 1: { name: 'bob', dinner: 'pizza' }, 2: { name: 'john', dinner: 'sushi' }, 3: { name: 'larry', dinner: 'hummus' } };
            
            console.log(findDinner('sushi', data));
            // => { name: 'john', dinner: 'sushi' }
            .as-console-wrapper {max-height: 100% !important; top: 0}
            &lt;script src="https://bundle.run/object-scan@13.8.0"&gt;&lt;/script&gt;

            免责声明:我是object-scan的作者

            【讨论】:

              猜你喜欢
              • 2017-12-02
              • 1970-01-01
              • 1970-01-01
              • 2019-12-12
              • 2021-11-14
              • 2018-01-02
              • 1970-01-01
              相关资源
              最近更新 更多