简体   繁体   中英

Find item in json object

Lets say this object

var paises = {
        "isora":  {
             leftX: '275',
             topY: '60',
             name: 'Gran Melia Palacio de Isora'
        },
        "pepe":  {
             leftX: '275',
             topY: '60',
             name: 'Gran Melia  de Don Pepe'
        },
        "australia":  {
             leftX: '565',
             topY: '220',
             name: 'Gran Melia Uluru'
        },
        "otro":  {            //    ejemplo
             leftX: '565',    //    cordenada x 
             topY: '220',     //    cordenada y
             name: 'soy otro' //    nombre a mostrar
        }  /*                 <==>  <span class="otro mPointer">isora</span> */
    }

Allright as you can see it has a id (isora,pepe, australia,otro) and each of those has cordinades (leftX, topY) and another name to show (name)

I am using this to geo tag pictures,
i already done the part where i hover an item and i highlight in the map the cordinades and the name to show, Now i need to do the opposite; if i hover the area in the map i need to highlight the item on the list (and in the map)

So lets say i have this mouse cordinades

x = 270

and     

y = 55   

how can i check if there is any item (id) with: x+-30 (leftX) AND y+-30 (topY) ??

+-30 is the margin of error (obviously is very dificult that users point exact cordinades with the mouse)

function find(x, y) {
    for (var key in paises) {
        if (paises.hasOwnProperty(key)) {
            var current = paises[key];

            if (Math.abs(current.leftX - x) < 30 && Math.abs(current.topY - y) < 30) {
                return current;
            }
        }
    }
}

You'd then call it by;

var found = find(270, 55);

if (found == undefined) {
    // none found
} else {
    // found = the one found!
}

Of course, you can easily change the function to return a boolean if you don't need the one that was matched.

for (var key in paises) {
    if (paises.hasOwnProperty(key)) {
        var item = paises[key];
        if (item.leftX > x - 30 && item.leftX < x + 30 &&
            item.topY > y - 30 && item.topY < y + 30) {
            // DO STUFF!
        }
    }
}

According to your description, you should rename leftX and topY as centerX and centerY instead.

But on another note, I would actually create clickable HTML elements instead using your object properties for positioning - and then hooking those elements up using the click event. That way, you'll never have to calculate anything, as you can change the size of the "clickable area" through simple CSS properties.

First, you could define a function that determines whether a point is inside the error margin:

function isInErrorMargin(px, py, vx, vy) { // p = reference point, v = actual point
    return vx >= px - 30
        && vx <= px + 30
        && vy >= py - 30
        && vy <= py + 30;
}

Then, iterate with $.each , checking each element:

var found;

$.each(paises, function() {
    if(isInErrorMargin(this.leftX, this.topY, x, y)) {
        found = this;
        return false; // stop
    }
});
function find(obj,test,args) {
    var ret = {};
    for(var i in obj) {

        if(obj.hasOwnProperty(i) && test.apply(obj[i],args) === true) {
            ret[i] = obj[i];
        }
    }
    return ret;
}

var paises = {
        "isora":  {
             leftX: '275',
             topY: '60',
             name: 'Gran Melia Palacio de Isora'
        },
        "pepe":  {
             leftX: '275',
             topY: '60',
             name: 'Gran Melia  de Don Pepe'
        },
        "australia":  {
             leftX: '565',
             topY: '220',
             name: 'Gran Melia Uluru'
        },
        "otro":  {            //    ejemplo
             leftX: '565',    //    cordenada x 
             topY: '220',     //    cordenada y
             name: 'soy otro' //    nombre a mostrar
        }  /*                 <==>  <span class="otro mPointer">isora</span> */
    }

var found = find(paises,function(x,y){
    if(this.hasOwnProperty("leftX") && this.hasOwnProperty("topY") && Math.abs(this.leftX - x) < 30 && Math.abs(this.topY - y) < 30) {
        return true;
    }
    else {
        return false;
    }
},[565,220]);
console.log(found)

This find algorythm searches in the obj (first argument) object for any object which return true to the test function (second argument). You can also pass arguments to the test function if you need.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM