关于jquery:在JavaScript对象数组中按id查找对象

Find object by id in an array of JavaScript objects

我有一个阵列:

1
myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}, etc.]

我无法更改数组的结构。我正在被传递一个45的ID,我想为数组中的那个对象获取'bar'

如何在JavaScript或使用jQuery中实现这一点?


由于您已经在使用jquery,因此可以使用grep函数来搜索数组:

1
var result = $.grep(myArray, function(e){ return e.id == id; });

结果是一个包含找到的项的数组。如果您知道对象总是在那里,并且只发生一次,那么您可以使用result[0].foo获取值。否则,您应该检查结果数组的长度。例子:

1
2
3
4
5
6
7
if (result.length == 0) {
  // not found
} else if (result.length == 1) {
  // access the foo property using result[0].foo
} else {
  // multiple items found
}


使用find()方法:

1
myArray.find(x => x.id === '45').foo;

来自MDN:

The find() method returns a value in the array, if an element in the array satisfies the provided testing function. Otherwise undefined is returned.

如果要查找其索引,请使用findIndex()

1
myArray.findIndex(x => x.id === '45');

来自MDN:

The findIndex() method returns the index of the first element in the array that satisfies the provided testing function. Otherwise -1 is returned.

如果要获取匹配元素的数组,请改用filter()方法:

1
myArray.filter(x => x.id === '45');

这将返回一个对象数组。如果要获取foo属性数组,可以使用map()方法执行此操作:

1
myArray.filter(x => x.id === '45').map(x => x.foo);

旁注:像find()filter()这样的方法和arrow函数不受旧浏览器(如ie)的支持,因此如果您想支持这些浏览器,应该使用babel(使用polyfill)来生成代码。


另一种解决方案是创建查找对象:

1
2
3
4
5
6
var lookup = {};
for (var i = 0, len = array.length; i < len; i++) {
    lookup[array[i].id] = array[i];
}

... now you can use lookup[id]...

如果需要进行许多查找,这尤其有趣。

这不需要更多的内存,因为ID和对象将被共享。


EcmaScript 2015在数组上提供find()方法:

1
2
3
4
var myArray = [
 {id:1, name:"bob
<div class="
suo-content">[collapse title=""]<ul><li>可能是因为它看起来仍然很有实验性,而且没有多少浏览器支持它,developer.mozilla.org/en-us/docs/web/javascript/reference/&hellip;</li><li>这可以简化为<wyn>myArray.find(d=>d.id===45).foo;</wyn>。</li><li>@蓬松的,甚至是埃多克斯1〔2〕。但这是一个旧的答案,它是在ES2015语法之前编写的,现在也得到了很好的支持。@gothdo的答案目前是线程中最新的。</li><li>@如果.find()返回undefined,那么优化会抛出一个错误。所以这个解决方案只能在保证匹配的情况下使用。</li><li>@Herbertters如果你想确保你可以一直检查空值,这将非常容易与可选的链接:<wyn>myArray.find(d => d.id === 45)?.foo</wyn>。</li><li>此解决方案适用于ES6,与IE浏览器不兼容。</li><li>@miladrashidi喜欢的答案是,如果你想要更旧的浏览器支持,有一个polyfill。同样,使用旧的语法也很容易重写。</li></ul>[/collapse]</div><p><center>[wp_ad_camp_1]</center></p><hr><P>.js有一个很好的方法:</P>[cc lang="javascript"]myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'},etc.]
obj = _.find(myArray, function(obj) { return obj.id == '45' })


我认为最简单的方法是如下,但它在Internet Explorer 8(或更早版本)上不起作用:

1
2
3
var result = myArray.filter(function(v) {
    return v.id === '45'; // Filter out the appropriate one
})[0].foo; // Get result and access the foo property


尝试以下操作

1
2
3
4
5
6
7
8
function findById(source, id) {
  for (var i = 0; i < source.length; i++) {
    if (source[i].id === id) {
      return source[i];
    }
  }
  throw"Couldn't find object with id:" + id;
}


1
myArray.filter(function(a){ return a.id == some_id_you_want })[0]


上面findbyid函数的通用和更灵活的版本:

1
2
3
4
5
6
7
8
9
10
11
12
// array = [{key:value},{key:value}]
function objectFindByKey(array, key, value) {
    for (var i = 0; i < array.length; i++) {
        if (array[i][key] === value) {
            return array[i];
        }
    }
    return null;
}

var array = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];
var result_obj = objectFindByKey(array, 'id', '45');


使用map()函数可以很容易地得到:

1
2
3
4
5
6
7
myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];

var found = $.map(myArray, function(val) {
    return val.id == 45 ? val.foo : null;
});

//found[0] =="bar";

工作示例:http://jsfiddle.net/hunter/pxaua/


你可以使用过滤器,

1
2
3
4
5
6
7
8
9
  function getById(id, myArray) {
    return myArray.filter(function(obj) {
      if(obj.id == id) {
        return obj
      }
    })[0]
  }

get_my_obj = getById(73, myArray);


使用本地Array.reduce

1
2
var array = [ {'id':'73' ,'foo':'bar'} , {'id':'45' ,'foo':'bar'} , ];
var id = 73;
1
2
3
var found = array.reduce(function(a, b){
    return (a.id==id && a) || (b.id == id && b)
});

如果找到,则返回对象元素,否则返回false


虽然这里有许多正确的答案,但其中许多答案并没有说明这样一个事实,即如果多次执行此操作,将是一个不必要的昂贵操作。在极端情况下,这可能是导致实际性能问题的原因。

在现实世界中,如果处理的项目很多,并且性能是一个问题,那么最初构建查找会更快:

1
2
3
var items = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];

var lookup = items.reduce((o,i)=>o[i.id]=o,{});

然后,您可以在固定时间内获取项目,如下所示:

1
var bar = o[id];

您还可以考虑使用映射而不是对象作为查找:https://developer.mozilla.org/en/docs/web/javascript/reference/global_objects/map


如果多次执行此操作,则可以设置地图(ES6):

1
const map = new Map( myArray.map(el => [el.id, el]) );

然后你可以简单地做:

1
map.get(27).foo


以下是我在纯JavaScript中的实现方式,在EcmaScript 3或更高版本中,这是我能想到的最简单的方式。一旦找到匹配项,它就会返回。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var getKeyValueById = function(array, key, id) {
    var testArray = array.slice(), test;
    while(test = testArray.pop()) {
        if (test.id === id) {
            return test[key];
        }
    }
    // return undefined if no matching id is found in array
    return;
}

var myArray = [{'id':'73', 'foo':'bar'}, {'id':'45', 'foo':'bar'}]
var result = getKeyValueById(myArray, 'foo', '45');

// result is 'bar', obtained from object with id of '45'

基于公认的答案:

jQuery:

1
2
var foo = $.grep(myArray, function(e){ return e.id === foo_id})
myArray.pop(foo)

或咖啡描述:

1
2
foo = $.grep myArray, (e) -> e.id == foo_id
myArray.pop foo

你可以在http://sugarjs.com/上试用sugarjs。

它在数组上有一个非常好的方法,.find。所以你可以找到这样的元素:

1
array.find( {id: 75} );

您还可以将具有更多属性的对象传递给它,以添加另一个"WHERE子句"。

注意,SugarJS扩展了本地对象,有些人认为这非常邪恶…


您甚至可以在纯JavaScript中使用内置的数组"filter"函数来实现这一点:

1
2
3
Array.prototype.filterObjects = function(key, value) {
    return this.filter(function(x) { return x[key] === value; })
}

现在只需将"id"替换为key,将"45"替换为value,就可以得到与id 45匹配的完整对象。那就是,

1
myArr.filterObjects("id","45");


迭代数组中的任何项。对于您访问的每个项目,请检查该项目的ID。如果匹配,请将其返回。

如果你只想得到编码:

1
2
3
4
5
6
7
8
function getId(array, id) {
    for (var i = 0, len = array.length; i < len; i++) {
        if (array[i].id === id) {
            return array[i];
        }
    }
    return null; // Nothing found
}

使用ecmascript 5的数组方法也一样:

1
2
3
4
5
6
7
8
function getId(array, id) {
    var obj = array.filter(function (val) {
        return val.id === id;
    });

    // Filter returns an array, and we just want the matching item.
    return obj[0];
}


使用Array.prototype.filter()功能。

演示:https://jsfiddle.net/sumitridhal/r0cz0w5o/4/

杰森

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var jsonObj =[
 {
 "name":"Me",
 "info": {
  "age":"15",
  "favColor":"Green",
  "pets": true
  }
 },
 {
 "name":"Alex",
 "info": {
  "age":"16",
  "favColor":"orange",
  "pets": false
  }
 },
{
 "name":"Kyle",
 "info": {
  "age":"15",
  "favColor":"Blue",
  "pets": false
  }
 }
];

滤波器

1
2
3
4
5
var getPerson = function(name){
    return jsonObj.filter(function(obj) {
      return obj.name === name;
    });
}


更通用、更简短

1
2
3
4
5
function findFromArray(array,key,value) {
        return array.filter(function (element) {
            return element[key] == value;
        }).shift();
}

在你的例子中,如var element = findFromArray(myArray,'id',45),它将给你整个元素。


As long as the browser supports ECMA-262, 5th edition (December 2009), this should work, almost one-liner:

1
2
3
var bFound = myArray.some(function (obj) {
    return obj.id === 45;
});


我真的很喜欢Aaron Digulla提供的答案,但是我需要保留我的对象数组,以便稍后迭代。所以我把它改成

1
2
3
4
5
6
7
    var indexer = {};
    for (var i = 0; i < array.length; i++) {
        indexer[array[i].id] = parseInt(i);
    }
   
    //Then you can access object properties in your array using
    array[indexer[id]].property


用途:

1
2
3
4
5
6
7
8
9
10
var retObj ={};
$.each(ArrayOfObjects, function (index, obj) {

        if (obj.id === '5') { // id.toString() if it is int

            retObj = obj;
            return false;
        }
    });
return retObj;

它应该按ID返回一个对象。


此解决方案也可能有帮助:

1
2
3
4
5
6
7
8
9
10
Array.prototype.grep = function (key, value) {
    var that = this, ret = [];
    this.forEach(function (elem, index) {
        if (elem[key] === value) {
            ret.push(that[index]);
        }
    });
    return ret.length < 2 ? ret[0] : ret;
};
var bar = myArray.grep("id","45");

我做得和$.grep一样,如果发现一个对象,函数将返回该对象,而不是一个数组。


最短的,

1
var theAnswerObj = _.findWhere(array, {id : 42});


将"axesOptions"视为对象格式为:field_type=>2,:fields=>[1,3,4]

1
2
3
4
5
6
7
8
function getFieldOptions(axesOptions,choice){
  var fields=[]
  axesOptions.each(function(item){
    if(item.field_type == choice)
        fields= hashToArray(item.fields)
  });
  return fields;
}

我们可以使用jquery方法$.each()/$.grep())var data= [];
$.each(array,function(i){if(n !== 5 && i > 4){data.push(item)}}

var data = $.grep(array, function( n, i ) {
return ( n !== 5 && i > 4 );
});

使用ES6语法:Array.find, Array.filter, Array.forEach, Array.map

或者使用lodash https://lodash.com/docs/4.17.10过滤器,下划线https://underlinejs.org/过滤器


从Aggaton的答案开始,这是一个函数,它实际上返回所需元素(如果找不到,则返回null),给定arraycallback函数,该函数返回"正确"元素的真实值:

1
2
3
4
5
6
7
8
9
function findElement(array, callback) {
    var elem;
    return array.some(function(e) {
        if (callback(e)) {
            elem = e;
            return true;
        }
    }) ? elem : null;
});

请记住,这在IE8-上并不适用,因为它不支持some。可以提供一个多填充物,或者总是有一个经典的for循环:

1
2
3
4
5
function findElement(array, callback) {
    for (var i = 0; i < array.length; i++)
        if (callback(array[i])) return array[i];
    return null;
});

它实际上更快更紧凑。但是如果你不想重新发明轮子,我建议你使用一个实用程序库,比如下划线或者lodash。


使用jquery的过滤方法:

1
2
3
4
 $(myArray).filter(function()
 {
     return this.id == desiredId;
 }).first();

它将返回具有指定ID的第一个元素。

它还有一个不错的C Linq格式的好处。