2013-06-25 84 views
2

用組找到所有可能的相關值的最佳方法是什麼?爲特定密鑰「過濾」JSON並獲取所有相關值

var table = [ 
    {group:"a", stuff:"new"}, 
    {group:"a", stuff:"old"}, 
    {group:"b", stuff:"newOld"}, 
    {group:"b", stuff:"old"}, 
    {group:"c", stuff:"new"}, 
    {group:"c", stuff:"old"}, 
    {group:"c", stuff:"newOld"}, 
]; 

我想填充包含唯一group值的下拉列表。並在選擇我想使用所有相關stuff進一步處理。並且還想添加一個包含所有stuff的組。例如

on selection of all -> new, old, newOld 
       a -> new, old 
       b -> newOld, old 
       c -> new, old, newOld 

回答

4

短而精確,沒有過度全陣列中的每個時間查找條目d:

var groups = {all:{}}; 
table.forEach(function(a){ 
    if (!groups[a.group]){ groups[a.group] = {}; } 
    groups[a.group][a.stuff] = groups["all"][a.stuff] = 1; 
}); 

列表中的對象的東西,因而沒有重複的條目(這就是爲什麼,而冗餘=1)。但是,你可以輕鬆地擴展它來計算的重複:

table.forEach(function(a){ 
    if (!groups[a.group]){ groups[a.group] = {}; } 
    var stuff = groups["all"][a.stuff]; 
    groups["all"][a.stuff] = !stuff ? 1 : ++stuff; 
    stuff = groups[a.group][a.stuff]; 
    groups[a.group][a.stuff] = !stuff ? 1 : ++stuff; 
}); 

結果將如下所示:

// "groups" holds all group elements and their stuff values 
groups = { "all": {"new":2,"old":3,"newOld":2}, 
      "a" : {"new":1,"old":1}, 
      "b" : {"newOld":1,"old":1}, 
      "c" : {"new":1,"old":1,"newOld":1} 
     } 

要檢索組的值,簡單地說:

var groupname = "a"; // whatever group you need 
Object.keys(groups[groupname]); 
// will give you: 
["new","old"] 

Demo

要注意支持當然是Object.keysArray.prototype.forEach

+0

這是很好的解決方案,那就是我一直在尋找的。我有點混淆我如何列出所有組名。因爲這只是一個例子,我擁有龐大的數據集,我想在其中實現這一點。 – apaleja

+0

@anand我延長了我的回答。這對你有幫助嗎? – Christoph

+0

+1這是爲了本地JS。你搖滾 –

0

你可能會想是這樣的:

var groups = {}, container = [], tracker = {}; 

for (var i = 0, l = table.length; i < l; i++) 
{ 
    var group = table[i].group, stuff = table[i].stuff; 

    if (!groups.hasOwnProperty(group)) groups[group] = []; 
    groups[group].push(stuff); 

    if (tracker.hasOwnProperty(stuff)) continue; 
    container.push(stuff); 
    tracker[group] = undefined; 
} 

當組包含該組數據的對象,容器包含所有唯一值。

+0

不應該在陣列上使用'for .. in' ... – Christoph

+0

公平點,但是我認爲如果有人正在改變陣列的原型,則會出現更大的問題... – pseux

+0

for..in不可靠地循環一個數組......不管你是否改變原型都沒關係。 – Christoph

0

我認爲這可以工作:

var table = [ 
    {group:"a", stuff:"new"}, 
    {group:"a", stuff:"old"}, 
    {group:"b", stuff:"newOld"}, 
    {group:"b", stuff:"old"}, 
    {group:"c", stuff:"new"}, 
    {group:"c", stuff:"old"}, 
    {group:"c", stuff:"newOld"} 
]; 
var groups = {}; 
var all = []; 

for(var i = 0; i < table.length; i++) { 
    var group = table[i];  

    if(typeof groups[group.group] === "undefined") { 
     groups[group.group] = []; 
    } 

    if (all.indexOf(group.stuff) == -1){ 
     all.push(group.stuff); 
    } 

    groups[group.group].push(
     group.stuff 
    );  
} 

all.sort(); 

所以變量all持有每一個可能的值和groups包含每個組的值:

console.log(groups.a) 
> ["new", "old"] 
console.log(groups.b) 
> ["newOld", "old"] 
console.log(groups.c) 
> ["new", "old", "newOld"] 
0

看樣品here

var table = [ 
    {group:"a", stuff:"new"}, 
    {group:"a", stuff:"old"}, 
    {group:"b", stuff:"newOld"}, 
    {group:"b", stuff:"old"}, 
    {group:"c", stuff:"new"}, 
    {group:"c", stuff:"old"}, 
    {group:"c", stuff:"newOld"}, 
]; 

    var filter = function(selected) {  
     var newArr = []; 
     $.each(table, function(idx, item){ 
      if((selected == null || selected == item.group) && $.inArray(item.stuff, newArr) == -1) { 
       newArr.push(item.stuff); 
      } 
     });  
     return newArr; 
    }; 

// using 
    console.log(filter('a')); 

// for selecting 'all' 
    console.log(filter(null)); 
3

SOLUTION:

使用grepmapunique(的unique使用可如果 「全部」 不需要移除)。下面的代碼:

function getOptions(value) { 
    //check if value sent in is an option or "All" options 
    var isAll = value === "All" ? true : false; 
    var forVal; 
    //If its "All" options 
    if (isAll) { 
     //yes, "All" has been chosen. yay! 

     //retreive all the values in "stuff" keys in array 
     var internal = $.map(table, function (r) { 
      return r["stuff"]; 
     }) 
     console.log(internal); 
     //get the unique values in internal[] 
     forVal = $.unique(internal); 

     //or use grep instead if u like to use unique with only DOM elements 

    } else { 

     //use grep to filter out the other options except the chosen option 
     var internal = $.grep(table, function (row) { 
      return row["group"] === value; 
     }); 

     //rip out the the values in "stuff" keys in internal[] 
     forVal = $.map(internal, function (r) { 
      return r["stuff"] 
     }); 
    } 
    //return the output variable 
    return forVal; 
} 

情景

我們已經得到了這些選項下拉 - abcAll

<select id="questions"> 
    <option>All</option> 
    <option>a</option> 
    <option>b</option> 
    <option>c</option> 
</select> 

當選擇一個option,你想從getOption()得到相關的輸出和顯示它作爲其他select

$("select").change(function() { 
    //remove all #result select boxes - litter of previous option selection 
    $("#result").remove(); 
    //get the options from the getOptions function 
    var source = getOptions(this.value); 
    //declare a select tag - will be inserted into <body> later 
    var $select = $("<select/>", { 
     "id": "result" 
    }); 
    //construct an array of <option> tags 
    var $options = $.map(source, function (r) { 
     return $("<option/>", { 
      "html": r 
     }); 
    }); 
    //append $options to <Select> and then append $select to <body> 
    $select.append($options).appendTo("body"); 
}); 

DEMO http://jsfiddle.net/hungerpain/tSR5P/

EXTRA INFO有關用於在該溶液中

map

  1. 文檔的方法:http://api.jquery.com/jQuery.map/
  2. 它做什麼:將數組或對象中的所有項目轉換爲新的項目數組。有點像你的json對象的重塑。

unique

  1. 文檔:http://api.jquery.com/jQuery.unique/
  2. 作用:刪除重複從陣列。

grep

  1. 文檔:http://api.jquery.com/jQuery.grep/
  2. 查找滿足過濾器功能的數組的元素。

希望這會有所幫助!

+0

這是一個很好的解決方案,但它不會爲我工作,因爲我有巨大的數據集,我需要動態創建下拉列表。 – apaleja

+0

@anand你可以!然後,您可以使用事件委託綁定更改事件並完成此項工作。 – krishgopinath