Reputation: 4539
I have the following structure in my JavaScript:
var map_neighbour_regions = [{
"id": 1,
"name": "Alaska",
"dom_element": "Alaska",
"continent_id": 1,
"neighbours": [{
"id": 1,
"region_id": 1,
"neighbour_region_id": 59
}, {
"id": 2,
"region_id": 1,
"neighbour_region_id": 64
}]
}, {
"id": 2,
"name": "Algeria",
"dom_element": "Algeria",
"continent_id": 1,
"neighbours": [{
"id": 3,
"region_id": 2,
"neighbour_region_id": 10
}, {
"id": 4,
"region_id": 2,
"neighbour_region_id": 19
}, {
"id": 5,
"region_id": 2,
"neighbour_region_id": 47
}, {
"id": 6,
"region_id": 2,
"neighbour_region_id": 52
}],
.....
}
In a loop, I want to find a given country, then access each neighbour country. I am not able to get this working.
I start with a country name, I want to find it in the list of first countries, then for each neighbour id get the name again from the first list.
I want to end up with (for example) an array of region names which are neighbours to the input country name. For an input country such as Argentine, I want to output:
neighbour_regions = {'chile', 'brazil', 'bolivia'};
I have tried without success (undefined) just to access the first level:
function highlightNeighbouringRegions(country) {
console.log(map_neighbour_regions [0][country]);
console.log(map_neighbour_regions [0].country);
console.log(map_neighbour_regions [country]);
};
I have added a JSFiddle here.
Upvotes: 2
Views: 268
Reputation: 148574
I like dynamic solutions.
Here is a recursive function which requires :
prop
name that you want to compare ("name
in your example")desiredValue
value that you want to compare to ("Argentina
in your example")So :
function findNode(prop, desiredValue, jsonObj)
{
if (!jsonObj || "object" !== typeof jsonObj) { return; }
if (jsonObj[prop] === desiredValue) { return jsonObj; }
for (var x in jsonObj)
{
if (Object.hasOwnProperty.call(jsonObj, x))
{
var result = findNode(prop, desiredValue, jsonObj[x]);
if (result !== undefined) { return result; }
}
}
}
And now you can do :
var a=findNode("name","Argentina",map_region_neighbours);
console.table(a.neighbours); //check for undefined etc...
Result :
http://jsfiddle.net/5tfnxwkw/2/
Edit:
After your comment , I enhanced the function.
Now the function takes Assertion
The assertion will check for condition/property to be present.
For example :
{
"id": 4,
"name": "Argentina",
"dom_element": "Argentina",
"continent_id": 1,
"neighbours": [{
"id": 9,
"region_id": 4,
"neighbour_region_id": 8
}
...
Let's look at id
: to which ID I'm referring ? the inner or outsider ?
So now the method looks like :
function findNode(prop, desiredValue, jsonObj,assertion)
So now if I supply :
findNode("id", ..., ...,'dom_element')
It will ALSO SEARCH FOR a sibling called dom_element
So this will match "id": 4,
.
So if your name is John and you have a brother named Paul , and you have also a son called John which has a brother named Ringo , so if I want to refer you - the trick here is to search "John" which has "Paul" sibling. ( and not ringo)
Ok but What if I want the inner id? "id": 9,
Then - You will call the method like :
findNode("id", ..., ...,'region_id')
So you actually help the method decide which node to chose.
OK so how the final code will look ?
var n=findNode("name","Alaska",map_region_neighbours,'name').neighbours;
n.forEach(function logArrayElements(element, index, array) {
console.log("******neighboors id "+(element["id"])+" has a name of : ");
console.log( findNode("id", element["id"], map_region_neighbours,'dom_element').name);
})
Result :
******neighboors id 1 has a name of :
Alaska
******neighboors id 2 has a name of :
Algeria
New jsbin : http://jsfiddle.net/5tfnxwkw/3/
Upvotes: 3
Reputation: 28397
I want to end up with (for example) an array of region names which are neighbours to the input country name. For an input country such as Argentine, I want to output:
neighbour_regions = {'chile', 'brazil', 'bolivia'};
Here is another way:
function getNeighbors(search) {
var found = regions.filter(function(s) { // filter regions for search term
return s.name == search;
})[0].neighbours.map(function(n) { // create array of ids from found items
return n.id;
});
// create and return an array of name from regions where id matches
return regions.reduce(function(result, r) {
if (found.indexOf(r.id) > -1) result.push(r.name);
return result;
}, []);
}
Calling this function as getNeighbors('Alaska')
will get you an array of neighbour names ["Algeria", "Antartica"]
.
Demo Fiddle: http://jsfiddle.net/abhitalks/zpgfjuc0/
Demo Snippet:
var regions = [{
"id": 1,
"name": "Alaska",
"dom_element": "Alaska",
"continent_id": 1,
"neighbours": [{
"id": 2,
"region_id": 1,
"neighbour_region_id": 59
}, {
"id": 3,
"region_id": 1,
"neighbour_region_id": 64
}]
}, {
"id": 2,
"name": "Algeria",
"dom_element": "Algeria",
"continent_id": 1,
"neighbours": [{
"id": 1,
"region_id": 2,
"neighbour_region_id": 10
}, {
"id": 4,
"region_id": 2,
"neighbour_region_id": 19
}]
}, {
"id": 3,
"name": "Antartica",
"dom_element": "AntarticWildlifeTerritory",
"continent_id": 1,
"neighbours": [{
"id": 1,
"region_id": 3,
"neighbour_region_id": 5
}, {
"id": 8,
"region_id": 3,
"neighbour_region_id": 49
}]
}, {
"id": 4,
"name": "Argentina",
"dom_element": "Argentina",
"continent_id": 1,
"neighbours": [{
"id": 2,
"region_id": 4,
"neighbour_region_id": 8
}, {
"id": 10,
"region_id": 4,
"neighbour_region_id": 9
}, {
"id": 11,
"region_id": 4,
"neighbour_region_id": 12
}, {
"id": 12,
"region_id": 4,
"neighbour_region_id": 50
}]
}];
function getNeighbors(country) {
var found = regions.filter(function(c) {
return c.name == country;
})[0].neighbours.map(function(n) {
return n.id;
});
return regions.reduce(function(result, r) {
if (found.indexOf(r.id) > -1) result.push(r.name);
return result;
}, []);
}
snippet.log(getNeighbors('Alaska'));
snippet.log(getNeighbors('Algeria'));
snippet.log(getNeighbors('Argentina'));
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Upvotes: 0
Reputation: 7597
Following code will show you in the console all neighbours of country name, that you have passed as a variable to the function highlightNeighbouringRegions
:
function highlightNeighbouringRegions(country) {
var result = [];
$.each(map_neighbour_regions, function(idx1, e1) {
if (e1.name === country) {
var neighbour_regions = [];
$.each(e1.neighbours, function(idx2, e2) {
neighbour_regions.push(e2.neighbour_region_id);
});
$.each(map_neighbour_regions, function(idx3, e3) {
if ($.inArray(e3.id, neighbour_regions) > -1) {
result.push(e3.name);
}
});
}
});
return result;
}
var neighbour_regions = highlightNeighbouringRegions('Alaska');
console.log(neighbour_regions);
This code will return you desired data - in neighbour_regions
you will have an array with all neighbours country names.
Upvotes: 0