首页 文章

通过属性值[duplicate]从对象数组中获取JavaScript对象

提问于
浏览
536

这个问题在这里已有答案:

假设我有一个包含四个对象的数组:

var jsObjects = [
   {a: 1, b: 2}, 
   {a: 3, b: 4}, 
   {a: 5, b: 6}, 
   {a: 7, b: 8}
];

有没有办法可以通过属性 b 的值获取第三个对象( {a: 5, b: 6} ),例如没有 for...in 循环?

17 回答

  • 0
    var jsObjects = [{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}, {a: 7, b: 8}];
    

    要访问第三个对象,请使用: jsObjects[2];
    要访问第三个对象b值,请使用: jsObjects[2].b;

  • 0

    要通过特定属性值从对象数组中获取第一个对象:

    function getObjectFromObjectsArrayByPropertyValue(objectsArray, propertyName, propertyValue) {
      return objectsArray.find(function (objectsArrayElement) {
        return objectsArrayElement[propertyName] == propertyValue;
      });
    }
    
    function findObject () {
      var arrayOfObjectsString = document.getElementById("arrayOfObjects").value,
          arrayOfObjects,
          propertyName = document.getElementById("propertyName").value,
          propertyValue = document.getElementById("propertyValue").value,
          preview = document.getElementById("preview"),
          searchingObject;
      
      arrayOfObjects = JSON.parse(arrayOfObjectsString);
      
      console.debug(arrayOfObjects);
      
      if(arrayOfObjects && propertyName && propertyValue) {
        searchingObject = getObjectFromObjectsArrayByPropertyValue(arrayOfObjects, propertyName, propertyValue);
        if(searchingObject) {
          preview.innerHTML = JSON.stringify(searchingObject, false, 2);
        } else {
          preview.innerHTML = "there is no object with property " + propertyName + " = " + propertyValue + " in your array of objects";
        }
      }
    }
    
    pre {
      padding: 5px;
      border-radius: 4px;
      background: #f3f2f2;
    }
    
    textarea, button {
      width: 100%
    }
    
    <fieldset>
      <legend>Input Data:</legend>
      <label>Put here your array of objects</label>
      <textarea rows="7" id="arrayOfObjects">
      [
        {"a": 1, "b": 2},
        {"a": 3, "b": 4},
        {"a": 5, "b": 6},
        {"a": 7, "b": 8, "c": 157}
      ]
      </textarea>
    
      <hr>
    
      <label>property name: </label> <input type="text" id="propertyName"  value="b"/>
      <label>property value: </label> <input type="text" id="propertyValue" value=6 />
         
    </fieldset>
    <hr>
    <button onclick="findObject()">find object in array!</button>
    <hr>
    <fieldset>
      <legend>Searching Result:</legend>
      <pre id="preview">click find</pre>
    </fieldset>
    
  • 9

    我不知道为什么你反对for循环(大概你的意思是for循环,而不是专门用于..in),它们快速且易于阅读 . 无论如何,这里有一些选择 .

    对于循环:

    function getByValue(arr, value) {
    
      for (var i=0, iLen=arr.length; i<iLen; i++) {
    
        if (arr[i].b == value) return arr[i];
      }
    }
    

    . 过滤

    function getByValue2(arr, value) {
    
      var result  = arr.filter(function(o){return o.b == value;} );
    
      return result? result[0] : null; // or undefined
    
    }
    

    .forEach

    function getByValue3(arr, value) {
    
      var result = [];
    
      arr.forEach(function(o){if (o.b == value) result.push(o);} );
    
      return result? result[0] : null; // or undefined
    
    }
    

    另一方面,如果您确实想要...而想要查找具有值为6的任何属性的对象,则必须使用for..in,除非您传递名称以进行检查 . 例如

    function getByValue4(arr, value) {
      var o;
    
      for (var i=0, iLen=arr.length; i<iLen; i++) {
        o = arr[i];
    
        for (var p in o) {
          if (o.hasOwnProperty(p) && o[p] == value) {
            return o;
          }
        }
      }
    }
    
  • -29

    OK, 有几种方法可以做到这一点,但让我们从最简单的方法和最新方法开始,这个函数叫做 find() .

    使用 find 时要小心,因为即使是IE11也不支持它,所以需要进行转换...

    所以你有这个对象,如你所说:

    var jsObjects = [
       {a: 1, b: 2}, 
       {a: 3, b: 4}, 
       {a: 5, b: 6}, 
       {a: 7, b: 8}
    ];
    

    你可以编写一个函数并得到它:

    function filterValue(obj, key, value) {
      return obj.find(function(v){ return v[key] === value});
    }
    

    并使用这样的功能:

    filterValue(jsObjects, "b", 6); //{a: 5, b: 6}
    

    同样在 ES6 中甚至缩短版本:

    const filterValue = (obj, key, value)=> obj.find(v => v[key] === value);
    

    此方法仅返回匹配...的第一个值,为了获得更好的结果和浏览器支持,您可以使用 filter

    const filterValue = (obj, key, value)=> obj.filter(v => v[key] === value);
    

    我们将返回 [{a: 5, b: 6}] ...

    这个方法将返回一个数组而不是......

    你也可以简单地使用循环,创建一个这样的函数:

    function filteredArray(arr, key, value) {
      const newArray = [];
      for(i=0, l=arr.length; i<l; i++) {
        if(arr[i][key] === value) {
          newArray.push(arr[i]);
        }
      }
     return newArray;
    }
    

    并称之为:

    filteredArray(jsObjects, "b", 6); //[{a: 5, b: 6}]
    
  • 134

    只是将this answer的最快/最佳部分改进为更可重用/清晰:

    function getElByPropVal(arr, prop, val){
        for (var i = 0, length = arr.length; i < length; i++) {
            if (arr[i][prop] == val){
                return arr[i];
            }
        }
    }
    
  • 19
    var result = jsObjects.filter(x=> x.b === 6);
    

    会更好,使用返回过滤器有时你不能得到结果(我不知道为什么)

  • 3
    jsObjects.find(x => x.b === 6)
    

    来自MDN:

    如果数组中的元素满足提供的测试函数,则find()方法返回数组中的值 . 否则返回undefined .


    附注:旧版浏览器(如IE)不支持 find() 和箭头函数等方法,因此如果要支持这些浏览器,则应使用Babel来转换代码 .

  • 209

    使用find with bind将特定键值传递给回调函数 .

    function byValue(o) { 
           return o.a === this.a && o.b === this.b; 
       };   
    
       var result = jsObjects.find(byValue.bind({ a: 5, b: 6 }));
    
  • 17

    如果您正在寻找单个结果,而不是数组,我可以建议减少吗?

    这是一个简单的'ole javascript中的解决方案,如果存在匹配对象,则返回匹配对象,否则返回null .

    var result = arr.reduce(function(prev, curr) { return (curr.b === 6) ? curr : prev; }, null);
    
  • 30

    尝试Array filter方法使用 property 过滤 array of objects .

    var jsObjects = [
       {a: 1, b: 2}, 
       {a: 3, b: 4}, 
       {a: 5, b: 6}, 
       {a: 7, b: 8}
    ];
    

    using array filter method:

    var filterObj = jsObjects.filter(function(e) {
      return e.b == 6;
    });
    

    using for in loop :

    for (var i in jsObjects) {
      if (jsObjects[i].b == 6) {
        console.log(jsObjects[i]); // {a: 5, b: 6}
      }
    }
    

    Working fiddle : https://jsfiddle.net/uq9n9g77/

  • 4

    如果我理解正确,你想找到 b 属性为 6 的数组中的对象?

    var found;
    jsObjects.some(function (obj) {
      if (obj.b === 6) {
        found = obj;
        return true;
      }
    });
    

    或者,如果您使用下划线:

    var found = _.select(jsObjects, function (obj) {
      return obj.b === 6;
    });
    
  • 12

    请参阅此文档https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values
    示例:

    var inventory = [
        {name: 'apples', quantity: 2},
        {name: 'bananas', quantity: 0},
        {name: 'cherries', quantity: 5}
    ];
    
    function findCherries(fruit) { 
        return fruit.name === 'cherries';
    }
    
    console.log(inventory.find(findCherries)); 
    // { name: 'cherries', quantity: 5 }
    
  • 1

    您可以将它与箭头功能一起使用,如下所示:

    var demoArray = [
       {name: 'apples', quantity: 2},
       {name: 'bananas', quantity: 0},
       {name: 'cherries', quantity: 5}
    ];
    
    var result = demoArray.filter( obj => obj.name === 'apples')[0];
    console.log(result);
    // {name: 'apples', quantity: 2}
    
  • 749

    使用underscore.js:

    var foundObject = _.findWhere(jsObjects, {b: 6});
    
  • 12

    Filter 对象数组,其属性与value匹配,返回数组:

    var result = jsObjects.filter(obj => {
      return obj.b === 6
    })
    

    MDN Docs on Array.prototype.filter()

    const jsObjects = [
      {a: 1, b: 2}, 
      {a: 3, b: 4}, 
      {a: 5, b: 6}, 
      {a: 7, b: 8}
    ]
    
    let result = jsObjects.filter(obj => {
      return obj.b === 6
    })
    
    console.log(result)
    

    Find 数组中第一个元素/对象的值,否则返回 undefined .

    var result = jsObjects.find(obj => {
      return obj.b === 6
    })
    

    MDN Docs on Array.prototype.find()

    const jsObjects = [
      {a: 1, b: 2}, 
      {a: 3, b: 4}, 
      {a: 5, b: 6}, 
      {a: 7, b: 8}
    ]
    
    let result = jsObjects.find(obj => {
      return obj.b === 6
    })
    
    console.log(result)
    
  • 5

    看起来在ECMAScript 6提案中有 Array 方法 find()findIndex() . MDN还提供了polyfills,您可以包含这些polyfill以在所有浏览器中获得这些功能 .

    find()

    function isPrime(element, index, array) {
        var start = 2;
        while (start <= Math.sqrt(element)) {
            if (element % start++ < 1) return false;
        }
        return (element > 1);
    }
    
    console.log( [4, 6, 8, 12].find(isPrime) ); // undefined, not found
    console.log( [4, 5, 8, 12].find(isPrime) ); // 5
    

    findIndex()

    function isPrime(element, index, array) {
        var start = 2;
        while (start <= Math.sqrt(element)) {
            if (element % start++ < 1) return false;
        }
        return (element > 1);
    }
    
    console.log( [4, 6, 8, 12].findIndex(isPrime) ); // -1, not found
    console.log( [4, 6, 7, 12].findIndex(isPrime) ); // 2
    
  • 14

    如何使用lo-dashlo-dash来通过对象属性值从对象数组中获取对象 . 你可以这样做:

    var o = _.find(jsObjects, {'b': 6});
    

    参数:

    collection (Array|Object): The collection to inspect.
    [predicate=_.identity] (Function): The function invoked per iteration.
    [fromIndex=0] (number): The index to search from.
    

    返回

    (*): Returns the matched element (in your case, {a: 5, b: 6}), else undefined.
    

    在性能方面, _.find() 更快,因为它只用属性 {'b': 6} 拉第一个对象,另一方面,如果假设你的数组包含多个具有匹配属性集(key:value)的对象,那么你应该考虑使用 _.filter() 方法 . 所以在你的情况下,由于你的数组有一个具有这个属性的对象,我会使用 _.find() .

相关问题