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 を返します。必要なのは、オブジェクトがこの配列にあるかどうかについての true/false 情報だけです。どうすればこれを達成できますか?

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 に答える
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

他の人が述べたように、オブジェクト自体を比較することによって 2 つの固有のオブジェクトの内容を比較することはできないため、それらのプロパティを比較する必要があります。Array.prototype.someECMA5 でこのようなことを行うことができますが、簡単に調整できます。

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について

または、あなたが提案したように、必要なだけtruefalse、さらに単純化できます。

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およびyaおよびに変更する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について

もちろん、一般的なルートをさらに進めて、再帰を導入することもできます。

于 2013-06-27T13:04:46.553 に答える
0

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});
于 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 に答える