2016-11-25 45 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展示如何設計結果。

我只希望有一種方法可以更簡潔地做到這一點。