2013-06-27 4 views
1

У меня есть массив координат, как это:Query массив объектов в JavaScript

coordinates = [ 
    {x: 1, y: 2}, 
    {x: 3, y: 4}, 
    {x: 5, y: 6}, 
    {x: 7, y: 8}, 
    {x: 9, y: 0} 
]; 

Я хочу, чтобы запросить этот массив для объекта, как это.

var searchFor = {x: 1, y: 2} 

Я попытался это:

if ($.inArray(searchFor, coordinates) !== -1) { 
     ... 
} 

Но это всегда возвращает -1. Все, что мне нужно, это true/false информация о том, находится ли объект в этом массиве. Как я могу это достичь?

+0

if (coord.indexOf (searchFor)! = -1) // существует – madhairsilence

+0

Вам нужно будет перебирать значения объекта в массиве, так как они представляют собой два отдельных объекта. Прямо сейчас вы ищете другой объект, который просто имеет одинаковые значения, поэтому он возвращает -1. –

+0

Вы можете использовать внешнюю библиотеку, например, underscore.js? –

ответ

4

Это связано с тем, что объекты не равны друг другу, даже если они имеют одинаковые свойства/значения, если они не являются одним и тем же экземпляром.

Что вы должны сделать, это вручную перебирать массив:

for(var i=0, l=coordinates.length, found = false; i<l; i++) { 
    if(coordinates[i].x == searchFor.x && coordinates[i].y == searchFor.y) { 
     found = true; 
     break; 
    } 
} 
if(found) { 
    // ... 
} 
+0

@limelights нет, inArray также ищет объектное равенство –

+0

@ArunPJohny Да, я нашел это сам, но спасибо! :) –

+0

Вот [jsFiddle] (http://jsfiddle.net/fDWYZ/). – Travesty3

0

использования ирисковой DB, Taffy DB

var coordinates = [ {x: 1, y: 2}, {x: 3, y: 4}, {x: 5, y: 6}, {x: 7, y: 8}, {x: 9, y: 0}]; 
var coordinatesDB = TAFFY(coordinates); 
res = coordinatesDB({x: 1, y: 2}); 
0

Вы можете использовать $.grep - http://api.jquery.com/jQuery.grep/

coordinates = [{x: 1, y: 2}, {x: 3, y: 4}, {x: 5, y: 6}, {x: 7, y: 8}, {x: 9, y: 0}]; 

var query = $.grep(coordinates, function(co){ return co.x == 1 && co.y == 2; }); 
var hasResult = (query.length !== 0) 
// query = {x: 1, y:2} - hasResult = true 
2

Если вы хотите удобное однострочное решение, вы можете работать с Lo-Dash.

_(coordinates).findIndex({x: 3, y: 4}) 
// 1 
1

Вот более общий подход для поиска объекта в массиве объектов:

Array.prototype.indexOfObj = function(o,exact){ 
    // make sure incoming parameter is infact an object 
    if (typeof o === 'object'){ 
     // iterate over the elements of the origin array 
     for (var i = 0; i < this.length; i++){ 
      var match = true, 
       to = this[i], 
       matchedKeys = []; 
      // search through o's keys and make sure they exist and 
      // match the keys in the origin array 
      for (var k in o){ 
       match &= o.hasOwnProperty(k) && to.hasOwnProperty(k); 
       if (match){ 
        matchedKeys.push(k); 
        match &= (k in to && to[k] == o[k]); 
       } 
      } 
      // if we need an exact match, map it backwards as well 
      // (all of o's keys == all of to's keys) 
      if (match && exact){ 
       for (var k in to){ 
        match &= to.hasOwnProperty(k); 
        // additional unmatched keys 
        if (match && matchedKeys.indexOf(k) == -1){ 
         match = false; 
         break; 
        } 
       } 
      } 
      // if it was a match, return the current key 
      if (match){ 
       return i; 
      } 
     } 
    } 
    // default to to match found result 
    return -1; 
} 

Затем, используя свой пример:

{x:98,y:99} non-exact = -1 
{x:98,y:99} exact  = -1 
{x:1}  non-exact = 0 
{x:1}  exact  = -1 
{x:5,y:6} non-exact = 2 
{x:5,y:6} exact  = 2 
+0

Вам нужно, чтобы вы переключились с 'for (var k in o)' на '$ .each()' или по крайней мере включили проверку 'if (o.hasOwnProperty (k)) ...'. – Tomalak

+1

@Tomalak: Ой, упс - все еще работаю на моем кофе. Спасибо за головы. ;-) –

0

Как уже отмечалось другими, вы можете не сравнивайте два уникальных объекта, сравнивая сами объекты, поэтому вам нужно сравнить их свойства. Вы можете сделать что-то подобное с помощью Array.prototype.some, который является ECMA5, но его можно легко подкрепить.

Javascript

function indexOfCoordinates(array, object) { 
    var index = -1; 

    array.some(function (coordinate, arrayIndex) { 
     if (coordinate.x === object.x && coordinate.y === object.y) { 
      index = arrayIndex; 
      return true; 
     } 

     return false; 
    }); 

    return index; 
} 

var coordinates = [ 
    {x: 1, y: 2}, 
    {x: 3, y: 4}, 
    {x: 5, y: 6}, 
    {x: 7, y: 8}, 
    {x: 9, y: 0} 
]; 

if (indexOfCoordinates(coordinates, {x: 5, y: 6}) !== -1) { 
    console.log("found"); 
} 

if (indexOfCoordinates(coordinates, {x: 9, y: 1}) === -1) { 
    console.log("not found"); 
} 

На jsfiddle

Или, как вы предложили, вы только хотите true или false, то вы можете еще больше упростить.

Javascript

function hasCoordinate(array, object) { 
    return array.some(function (coordinate) { 
     return coordinate.x === object.x && coordinate.y === object.y; 
    }); 
} 

var coordinates = [ 
    {x: 1, y: 2}, 
    {x: 3, y: 4}, 
    {x: 5, y: 6}, 
    {x: 7, y: 8}, 
    {x: 9, y: 0} 
]; 

if (hasCoordinate(coordinates, {x: 1, y: 2})) { 
    console.log("found"); 
} 

if (!hasCoordinate(coordinates, {x: 9, y: 1})) { 
    console.log("not found"); 
} 

На jsfiddle

Это может быть дополнительно обобщена с использованием методов ECMA5 Object.keys и Array.prototype.map, вы должны, например, изменить ссылки x и y к a и b, или расширить свои координаты включить z. Теперь ваша функция будет работать без изменения.

Javascript

function hasCoordinate(array, object) { 
    var objectKeys = Object.keys(object).sort(), 
     objectValues = objectKeys.map(function (value) { 
      return object[value]; 
     }); 

    return array.some(function (coordinate) { 
     var coordinateKeys = Object.keys(coordinate).sort(), 
      coordinateValues = coordinateKeys.map(function (value) { 
       return coordinate[value]; 
      }); 

     return coordinateKeys.toString() === objectKeys.toString() && coordinateValues.toString() === objectValues.toString(); 
    }); 
} 

var coordinates = [ 
    {x: 1, y: 2}, 
    {x: 3, y: 4}, 
    {x: 5, y: 6}, 
    {x: 7, y: 8}, 
    {x: 9, y: 0} 
]; 

if (hasCoordinate(coordinates, {x: 1, y: 2})) { 
    console.log("found"); 
} 

if (!hasCoordinate(coordinates, {x: 9, y: 1})) { 
    console.log("not found"); 
} 

На jsfiddle

Конечно, вы могли бы продолжать дальше по родовому пути, и даже ввести рекурсию.