简体   繁体   English

遍历数组数组以查找一个国家的邻居

[英]Loop through array of arrays to find a countrys neighbors

I have the following structure in my JavaScript: 我的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. 我从一个国家名称开始,我想在第一个国家的列表中找到它,然后为每个邻居ID从第一个列表中再次获得该名称。

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 . 在这里添加了JSFiddle

I like dynamic solutions. 我喜欢动态解决方案。

Here is a recursive function which requires : 这是一个递归函数,它需要:

  • The prop name that you want to compare (" name in your example") 您要比较的prop名称(“示例name ”)
  • The desiredValue value that you want to compare to (" Argentina in your example") 您要与之比较的desiredValue值(“您的示例中为Argentina ”)

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/ http://jsfiddle.net/5tfnxwkw/2/

Edit: 编辑:

After your comment , I enhanced the function. 在您发表评论后,我增强了功能。

Now the function takes Assertion 现在该函数需要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 ? 让我们看一下id我指的是哪个ID 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 还将搜索名为dom_element兄弟姐妹

So this will match "id": 4, . 因此,它将匹配"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. 因此,如果您的名字叫John并且您有一个叫Paul的兄弟,并且您还有一个叫John的儿子,有一个叫Ringo的兄弟,那么如果我想推荐您-这里的诀窍是搜索带有“ Paul”的“ John”兄弟姐妹。 ( and not ringo) (而不是铃声)

Ok but What if I want the inner id? 好的,但是如果我想要内部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/ 新的jsbin: http : //jsfiddle.net/5tfnxwkw/3/

Following code will show you in the console all neighbours of country name, that you have passed as a variable to the function highlightNeighbouringRegions : 以下代码将在控制台中向您显示国家/地区名称的所有邻居,您已将它们作为变量传递给函数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. 此代码将返回您所需的数据-在neighbour_regions您将拥有一个包含所有邻居国家/地区名称的数组。

DEMO DEMO

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"] . getNeighbors('Alaska')调用此函数将获得一个邻居名称数组["Algeria", "Antartica"]

Demo Fiddle : http://jsfiddle.net/abhitalks/zpgfjuc0/ 演示小提琴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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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