2016-11-25 88 views
2

的阵列动态创建分组列表我有对象的嵌套阵列如下:使用对象

result = [ 
      [{"country":"France","continent":"Europe","name":"street a"}], 
      [{"country":"Brazil","continent":"South America", "name":"street b"},{"country":"Brazil","continent":"South America", "name":"street c"}], 
      [{"country":"Germany","continent":"Europe","name":"street d"}] 
     ] 

注意,这是从对象的排序,使用大陆和然后是国家密钥后的阵列产生。

我要动态地生成一个列表如下(大陆,然后国家),并把它添加到div

  1. 欧洲
    • 法国
    • 德国
      • 街道d
  2. 南美
    • 巴西
      • 街道b
      • 街道ç

每次返回的国家和大洲都会有所不同,但结果数组将按照大陆,国家的顺序进行分组。

由于我是HTML,CSS和JavaScript的新手,我无法弄清楚如何动态创建这个列表。到目前为止,我已成功使用仅生成大陆的唯一列表:

for(var i=0;i<result.length;i++){ 
    if($('#continent-list li').filter(function(){ 
     return $(this).text() == result[i][0].continent; 
    }).length == 0){ 
     $('#continent-list').append('<li>'+result[i][0].continent+'<ul></ul></li>'); 
} 

即我遍历列表,只有懒得看的第一个元素[结果[I] [0]),并添加这到一个叫做'continent-list'的无序列表。每次我也检查这个名字是否已经存在于无序列表中,如果它不存在,只有我添加。

+1

你的json中有几个语法错误。这些问题是真的还是错字?你能解决这个问题吗? – Taplar

+0

这里没有涉及到JSON。请阅读'json'标签的使用说明。 – trincot

回答

1

我认为要做到这一点的方法之一是遍历数组中的对象,并创建可用于大陆的div,同时确保没有大陆创建不止一次则仍然使用相同的循环中,您可以使用类似

更多
for(i=0;i<=results.length;i++){ 
    if (result[i].continent == continent) //here talking about the present continent in the main loop{ 
    //code to create new div for the current country....then same procedure for the street part.... 
    } 
} 

,对不起,我不是太冠冕堂皇jqueryish:d但我真的希望你的范围

0
var countries =[[{"country":"France","continent":"Europe","name":"street a"}], [{"country":"Brazil","continent":"South America", "name":"street b"}{"country":"Brazil","continent":"South America", "name":"street c"}], [{"country":"Germany","continent":"Europe","name":"street d"}]]; 

     var modified = {}; 

     for(var i =0; i<countries.length; i++){ 
      var continent = countries[i]; 
      for(var j =0;j<continent.length;j++){ 
       var country = continent[j]; 
       if(!modified[country.continent]){ 
       modified[country.continent] ={} 
       } 
       if(!modified[country.continent][country.country]){ 
       modified[country.continent][country.country] =[] 
       } 
       modified[country.continent][country.country].push(country); 
     } 
    } 
    var liText = "<ul>"; 
    for (var key in modified) { 
    liText += "<li>"+key + "<ul>"; 
    for (var country in modified[key]){ 
     liText += "<li>"+country + "<ul>"; 
     for(var i=0;i< modified[key][country].length;i++){ 
     liText += "<li>"+modified[key][country][i].name + "</ll>"; 
     } 
     liText += "</ul></li>"; 
    }; 
    liText += "</ul></li>"; 
     }; 
     liText += "</ul>" 

console.log(liText); 

document.getElementById('continent-list').innerHTML = liText; 
+0

谢谢!这工作。 – rj91

0

我就让你处理重复,但是这应该给你的总体思路:

jsFiddle

function displayData(continent, country, street) { 
    console.log(continent + ', ' + country + ', ' + street); 
    var output = $('#output'); 

    var continentLI = document.createElement('li'); 
    var continentTextNode = document.createTextNode(continent); 

    continentLI.appendChild(continentTextNode); 

    var countryUL = document.createElement('ul'); 
    var countryLI = document.createElement('li'); 
    var countryTextNode = document.createTextNode(country); 
    countryLI.appendChild(countryTextNode); 
    countryUL.appendChild(countryLI); 

    var streetUL = document.createElement('ul'); 
    var streetLI = document.createElement('li'); 
    var streetTextNode = document.createTextNode(street); 

    streetLI.appendChild(streetTextNode); 
    streetUL.appendChild(streetLI); 
    countryLI.appendChild(streetUL); 

    continentLI.appendChild(countryUL); 
    output.append(continentLI); 
}; 

$.each(result, function(resultKey, resultValue) { 
    var country = resultValue; 
    $.each(country, function(countryKey, countryValue) { 
    var continent = countryValue.continent; 
    var country = countryValue.country; 
    var street = countryValue.name; 
    displayData(continent, country, street); 
    }); 
}); 
0

你可以扁平的阵列,排序性能continentcountrystreet和更改组时建立的所有新的列表。

var result = [[{ "country": "France", "continent": "Europe", "name": "street a" }], [{ "country": "Brazil", "continent": "South America", "name": "street b" }, { "country": "Brazil", "continent": "South America", "name": "street c" }], [{ "country": "Germany", "continent": "Europe", "name": "street d" }]], 
 
    flat = result.reduce(function (r, a) { 
 
     return r.concat(a); 
 
    }, []), 
 
    ol = document.createElement('ol'), 
 
    ul1, ul2; 
 

 
flat.sort(function (a, b) { 
 
    return a.continent.localeCompare(b.continent) || a.country.localeCompare(b.country) || a.name.localeCompare(b.name); 
 
}); 
 

 
flat.forEach(function (a, i, aa) { 
 
    var li; 
 
    if (!i || aa[i - 1].continent !== a.continent) { 
 
     li = document.createElement('li'); 
 
     li.appendChild(document.createTextNode(a.continent)); 
 
     ol.appendChild(li); 
 
     ul1 = document.createElement('ul'); 
 
     ol.appendChild(ul1); 
 
    } 
 
    if (!i || aa[i - 1].country !== a.country) { 
 
     li = document.createElement('li'); 
 
     li.appendChild(document.createTextNode(a.country)); 
 
     ul1.appendChild(li); 
 
     ul2 = document.createElement('ul'); 
 
     ul1.appendChild(ul2); 
 
    } 
 
    li = document.createElement('li'); 
 
    li.appendChild(document.createTextNode(a.name)); 
 
    ul2.appendChild(li); 
 
}); 
 

 
document.getElementById('out').appendChild(ol);
<div id="out"></div>

+0

这真的很好!谢谢。 – rj91

0

我想大多数的工作都可以用数组减少函数来完成;)

第1步:我们会将您的数组转换成结构需要:

var result = [ 
    [{"country": "France", "continent": "Europe", "name": "street a"}], 
    [{"country": "Brazil", "continent": "South America", "name": "street b"}, { 
     "country": "Brazil", 
     "continent": "South America", 
     "name": "street c" 
    }], 
    [{"country": "Germany", "continent": "Europe", "name": "street d"}] 
]; 

// fatten the arrays into single array 
var continents = result.reduce(function (a, b) { 
    return a.concat(b); 
}); 

// group by continent 
continents = continents.reduce(function (a, b) { 
    if (a[b.continent]) { 
     a[b.continent].push(b); 
    } else { 
     a[b.continent] = [b]; 
    } 
    return a; 
}, {}); 

// group by country 
Object.keys(continents).forEach(function (continent) { 
    continents[continent] = continents[continent].reduce(function (a, b) { 
     if (a[b.country]) { 
      a[b.country].push(b); 
     } else { 
      a[b.country] = [b]; 
     } 
     return a; 
    }, {}); 
}); 

现在这就是您的continents数据对象应该如何上厕所K类似于:

{ 
    "Europe": { 
    "France": [ 
     { 
     "country": "France", 
     "continent": "Europe", 
     "name": "street a" 
     } 
    ], 
    "Germany": [ 
     { 
     "country": "Germany", 
     "continent": "Europe", 
     "name": "street d" 
     } 
    ] 
    }, 
    "South America": { 
    "Brazil": [ 
     { 
     "country": "Brazil", 
     "continent": "South America", 
     "name": "street b" 
     }, 
     { 
     "country": "Brazil", 
     "continent": "South America", 
     "name": "street c" 
     } 
    ] 
    } 
} 

第2步:

// create continents list 
var $list = $('<ol id="continent-list"/>'); 
Object.keys(continents).forEach(function (continentName) { 
    // create continent 
    var $continent = $('<li class="continent"/>').append($("<span/>").text(continentName)); 

    // add countries 
    var $countries = $('<ul class="country-list"/>'); 
    var continent = continents[continentName]; 
    Object.keys(continent).forEach(function (countryName) { 
     var $country = $('<li/>').append($("<span/>").text(countryName)); 
     // add streets 
     var $streets = $('<ul class="street-list"/>'); 
     var country = continent[countryName]; 
     country.forEach(function (street) { 
      var $street = $('<li/>').text(street.name); 
      $streets.append($street); 
     }); 
     $country.append($streets); 
     $countries.append($country); 
    }); 
    $continent.append($countries); 

    // add continent to the list 
    $list.append($continent); 
}); 

现在这是应该如何$list样子:

<ol id="continent-list"> 
    <li class="continent"><span>Europe</span> 
     <ul class="country-list"> 
      <li><span>France</span> 
       <ul class="street-list"> 
        <li>street a</li> 
       </ul> 
      </li> 
      <li><span>Germany</span> 
       <ul class="street-list"> 
        <li>street d</li> 
       </ul> 
      </li> 
     </ul> 
    </li> 
    <li class="continent"><span>South America</span> 
     <ul class="country-list"> 
      <li><span>Brazil</span> 
       <ul class="street-list"> 
        <li>street b</li> 
        <li>street c</li> 
       </ul> 
      </li> 
     </ul> 
    </li> 
</ol> 

我们将使用JQuery这个对象转换成HTML元素步骤3只需将其附加到文档中,例如:

$("body").append($list); 
0

这不是世界上最简单的要求/要求,但也不是特别复杂。它困扰我,它需要很多代码来解决。我不知道库,使这个问题微不足道的,但有两个说起来很方便:

首先,你的记录过度嵌套。为了使它们方便渲染,它们应该变平。下划线可以在一行做到这一点:

var flat = _.flatten(result); 

这是不是很难以纯JS:与移动

var flat = []; 
result.forEach(sublist => { 
    sublist.forEach(item => flat.push(item)); 
}); 

但它很高兴能够“一招去做”上。

然后你想要几个层次的嵌套。 Underscore有一个不错的groupBy功能,但它是单层的。这里还有其他多层次的扩展,但是这更加令人费解。 D3,然而,管理嵌套很容易:

var nested = d3.nest() 
       .key(d => d.continent) 
       .key(d => d.country) 
       .entries(flat); 

然后嵌套数据结构需要被渲染为HTML。你可以直接用HTML来做到这一点,但这有点麻烦。值得庆幸的是,浏览器有很好的管理DOM的工具,也就是它们的HTML内部表示。 D3擅长操纵它。

function nested2html(e, n, level) { 
    level = level || 0; 
    if (typeof e === 'string') e = d3.select(e); 
    var list = e.append(level ? 'ul' : 'ol') 
       .attr('class', 'level' + (level+1)); 
    var leafNode = !n[0].key; 
    n.forEach(nitem => { 
    if (leafNode) { 
     list.append('li').text(nitem.name); 
    } else { 
     var li = list.append('li'); 
     li.append('span').text(nitem.key); 
     nested2html(li, nitem.values, level + 1); 
    } 
    }); 
} 

// now add it to the document 
nested2html('body', nested); 

这不是特别复杂,因为递归程序去,并呈现出成结构良好,很容易地称呼HTML:

<ol class="level1"> 
    <li> 
    <span>Europe</span> 
    <ul class="level2"> 
     <li> 
     <span>France</span> 
     <ul class="level3"> 
      <li>street a</li> 
     </ul> 
     </li> 
     <li> 
     <span>Germany</span> 
     <ul class="level3"> 
      <li>street d</li> 
     </ul> 
     </li> 
    </ul> 
    </li> 
    <li> 
    <span>South America</span> 
    <ul class="level2"> 
     <li> 
     <span>Brazil</span> 
     <ul class="level3"> 
      <li>street b</li> 
      <li>street c</li> 
     </ul> 
     </li> 
    </ul> 
    </li> 
</ol> 

一个JSFiddle与运行的代码,以及一些可选的CSS展示如何设计结果。

我只希望有一种方法可以更简洁地做到这一点。