1

我有一个这样的坐标数组:

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。我需要的只是关于对象是否在这个数组中的真/假信息。我怎样才能做到这一点?

4

6 回答 6

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) {
    // ...
}
于 2013-06-27T12:25:36.160 回答
2

如果您想要一个方便的单线解决方案,您可以使用Lo-Dash

_(coordinates).findIndex({x: 3, y: 4})
// 1
于 2013-06-27T12:30:43.510 回答
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
于 2013-06-27T12:32:29.007 回答
0

使用太妃糖 DB、太妃糖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});
于 2013-06-27T12:28:59.940 回答
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
于 2013-06-27T12:29:06.900 回答
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.keysArray.prototype.map例如,如果您将引用x和更改yab,或者将坐标扩展为包括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 上

当然,您可以沿着通用路线继续前进,甚至引入递归。

于 2013-06-27T13:04:46.553 回答