Query array of objects in JavaScript - Stack Overflow

I have an array of coordinates like this:coordinates = [{x: 1, y: 2},{x: 3, y: 4},{x: 5, y: 6},{x: 7, y

I have an array of coordinates like this:

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

I want to query this array for an object like this.

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

I tried this:

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

But this always return -1. All I need is true/false info about whether the object is in this array. How can I achieve this?

I have an array of coordinates like this:

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

I want to query this array for an object like this.

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

I tried this:

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

But this always return -1. All I need is true/false info about whether the object is in this array. How can I achieve this?

Share Improve this question asked Jun 27, 2013 at 12:22 BananaBanana 4,2389 gold badges37 silver badges49 bronze badges 3
  • if( coordinates.indexOf(searchFor) != -1) // exists – madhairsilence Commented Jun 27, 2013 at 12:24
  • You'd need to iterate over the object's values in the array, as they are two separate objects. Right now, you're looking for another object that just happens to have the same values, which is why it's returning -1. – Qantas 94 Heavy Commented Jun 27, 2013 at 12:25
  • are you free to use external library like underscore.js ? – Parthik Gosar Commented Jun 27, 2013 at 12:26
Add a ment  | 

6 Answers 6

Reset to default 4

This is because objects are not equal to each other - even if they have the same properties/values - unless they are the exact same instance.

What you would have to do is manually iterate through the array:

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) {
    // ...
}

If you want a convenient one-liner solution, you could work with Lo-Dash.

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

Here's a more generic approach for searching for an object within the array of objects:

Array.prototype.indexOfObj = function(o,exact){
    // make sure ining 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;
}

Then, using your example:

{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

use taffy 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});

You could use $.grep - http://api.jquery./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

As mentioned by others, you can not pare two unique objects contents by paring the objects themselves, so you have to pare their properties. You could do something like this with Array.prototype.some which is ECMA5 but can easily be shimmed.

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");
}

On jsfiddle

Or as you suggested, you only want true or false then you can further simplify.

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");
}

On jsfiddle

This could be further generalised using ECMA5 methods Object.keys and Array.prototype.map, should you for example, change the references x and y to a and b, or extend your coordinates to include z. Now your function would still work without need of alteration.

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");
}

On jsfiddle

Of course you could continue further along the generic route, and even introduce recursion.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745339035a4623238.html

相关推荐

  • Query array of objects in JavaScript - Stack Overflow

    I have an array of coordinates like this:coordinates = [{x: 1, y: 2},{x: 3, y: 4},{x: 5, y: 6},{x: 7, y

    4小时前
    30

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信