2014-01-24 40 views
0

在我小的应用程序,我有一个函数返回树状数据:获得独特元素的列表,从树形对象

function getData() { 
return { 
    "name": "fish", 
     "children": [{ 
     "name": "mussels & clams", 
      "children": [{ 
      "name": "fennel", 
       "size": 1 
     }, { 
      "name": "garlic", 
       "size": 1 
     }, { 
      "name": "lemon", 
       "size": 1 
     }, { 
      "name": "onion", 
       "size": 1 
     }, { 
      "name": "parsley", 
       "size": 1 
     }, { 
      "name": "pasta", 
       "size": 1 
     }, { 
      "name": "rice", 
       "size": 1 
     }, { 
      "name": "soup", 
       "size": 1 
     }, { 
      "name": "tomato", 
       "size": 1 
     }] 
    }, { 
     "name": "octopus", 
      "children": [{ 
      "name": "bay", 
       "size": 1 
     }, { 
      "name": "chilli", 
       "size": 1 
     }, { 
      "name": "lemon", 
       "size": 1 
     }, { 
      "name": "olive oil", 
       "size": 1 
     }, { 
      "name": "paprika", 
       "size": 1 
     }, { 
      "name": "parsley", 
       "size": 1 
     }, { 
      "name": "pine nuts", 
       "size": 1 
     }] 
    }, { 
     "name": "oysters", 
      "children": [{ 
      "name": "asparagus", 
       "size": 1 
     }, { 
      "name": "bacon", 
       "size": 1 
     }, { 
      "name": "butter", 
       "size": 1 
     }, { 
      "name": "cellery", 
       "size": 1 
     }, { 
      "name": "chives", 
       "size": 1 
     }, { 
      "name": "garlic", 
       "size": 1 
     }, { 
      "name": "lemon", 
       "size": 1 
     }, { 
      "name": "mozzarella", 
       "size": 1 
     }, { 
      "name": "onion", 
       "size": 1 
     }, { 
      "name": "pasta", 
       "size": 1 
     }, { 
      "name": "parsley", 
       "size": 1 
     }, { 
      "name": "shallot", 
       "size": 1 
     }] 
    }, { 
     "name": "pink fish", 
      "children": [{ 
      "name": "balsamic vinegar", 
       "size": 1 
     }, { 
      "name": "chives", 
       "size": 1 
     }, { 
      "name": "cream", 
       "size": 1 
     }, { 
      "name": "dill", 
       "size": 1 
     }, { 
      "name": "garlic", 
       "size": 1 
     }, { 
      "name": "ham", 
       "size": 1 
     }, { 
      "name": "honey", 
       "size": 1 
     }, { 
      "name": "lemon", 
       "size": 1 
     }, { 
      "name": "lime", 
       "size": 1 
     }, { 
      "name": "mild cheese", 
       "size": 1 
     }, { 
      "name": "miso", 
       "size": 1 
     }, { 
      "name": "potato", 
       "size": 1 
     }, { 
      "name": "sesame", 
       "size": 1 
     }, { 
      "name": "soy souce", 
       "size": 1 
     }, { 
      "name": "spinach", 
       "size": 1 
     }, { 
      "name": "thyme", 
       "size": 1 
     }] 
    }, { 
     "name": "shrimp", 
      "children": [{ 
      "name": "coriander", 
       "size": 1 
     }, { 
      "name": "curry", 
       "size": 1 
     }, { 
      "name": "ginger", 
       "size": 1 
     }, { 
      "name": "lemon", 
       "size": 1 
     }, { 
      "name": "lime", 
       "size": 1 
     }, { 
      "name": "lobster", 
       "size": 1 
     }, { 
      "name": "parsley", 
       "size": 1 
     }, { 
      "name": "soft cheese", 
       "size": 1 
     }, { 
      "name": "tomato", 
       "size": 1 
     }] 
    }, { 
     "name": "smoked fish", 
      "children": [{ 
      "name": "asparagus", 
       "size": 1 
     }, { 
      "name": "butter", 
       "size": 1 
     }, { 
      "name": "eggs", 
       "size": 1 
     }, { 
      "name": "lemon", 
       "size": 1 
     }, { 
      "name": "mandarin", 
       "size": 1 
     }, { 
      "name": "mild cheese", 
       "size": 1 
     }, { 
      "name": "mushrooms", 
       "size": 1 
     }, { 
      "name": "onion", 
       "size": 1 
     }, { 
      "name": "potato", 
       "size": 1 
     }, { 
      "name": "spring onion", 
       "size": 1 
     }] 
    }, { 
     "name": "squid", 
      "children": [{ 
      "name": "bacon", 
       "size": 1 
     }, { 
      "name": "courgette", 
       "size": 1 
     }, { 
      "name": "cumin", 
       "size": 1 
     }, { 
      "name": "garlic", 
       "size": 1 
     }, { 
      "name": "lemon", 
       "size": 1 
     }, { 
      "name": "lime", 
       "size": 1 
     }, { 
      "name": "onion", 
       "size": 1 
     }, { 
      "name": "parsley", 
       "size": 1 
     }, { 
      "name": "peper", 
       "size": 1 
     }, { 
      "name": "rocket", 
       "size": 1 
     }, { 
      "name": "thyme", 
       "size": 1 
     }] 
    }, { 
     "name": "sushi", 
      "children": [{ 
      "name": "coriander", 
       "size": 1 
     }, { 
      "name": "couscous", 
       "size": 1 
     }, { 
      "name": "cucumber", 
       "size": 1 
     }, { 
      "name": "ginger", 
       "size": 1 
     }, { 
      "name": "lemon", 
       "size": 1 
     }, { 
      "name": "lime", 
       "size": 1 
     }, { 
      "name": "pepper", 
       "size": 1 
     }, { 
      "name": "rice", 
       "size": 1 
     }, { 
      "name": "sesame", 
       "size": 1 
     }, { 
      "name": "soya souce", 
       "size": 1 
     }, { 
      "name": "spring onion", 
       "size": 1 
     }, { 
      "name": "wasabi", 
       "size": 1 
     }] 
    }, { 
     "name": "white fish", 
      "children": [{ 
      "name": "butter", 
       "size": 1 
     }, { 
      "name": "courgette", 
       "size": 1 
     }, { 
      "name": "gream", 
       "size": 1 
     }, { 
      "name": "fennel", 
       "size": 1 
     }, { 
      "name": "french beans", 
       "size": 1 
     }, { 
      "name": "garlic", 
       "size": 1 
     }, { 
      "name": "leak", 
       "size": 1 
     }, { 
      "name": "lemon", 
       "size": 1 
     }, { 
      "name": "lime", 
       "size": 1 
     }, { 
      "name": "mild cheese", 
       "size": 1 
     }, { 
      "name": "onion", 
       "size": 1 
     }, { 
      "name": "parsley", 
       "size": 1 
     }, { 
      "name": "soup", 
       "size": 1 
     }, { 
      "name": "soya souce", 
       "size": 1 
     }, { 
      "name": "tomato", 
       "size": 1 
     }] 
    }, { 
     "name": "caviar", 
      "children": [{ 
      "name": "chives", 
       "size": 1 
     }, { 
      "name": "eggs", 
       "size": 1 
     }, { 
      "name": "sour cream", 
       "size": 1 
     }, { 
      "name": "strong cheese", 
       "size": 1 
     }] 
    }, { 
     "name": "lobster & crab", 
      "children": [{ 
      "name": "chili", 
       "size": 1 
     }, { 
      "name": "coriander", 
       "size": 1 
     }, { 
      "name": "fennel", 
       "size": 1 
     }, { 
      "name": "ginger", 
       "size": 1 
     }, { 
      "name": "leek", 
       "size": 1 
     }, { 
      "name": "mayonnaise", 
       "size": 1 
     }, { 
      "name": "parsley", 
       "size": 1 
     }, { 
      "name": "pasta", 
       "size": 1 
     }, { 
      "name": "peas", 
       "size": 1 
     }, { 
      "name": "rice", 
       "size": 1 
     }, { 
      "name": "sesame", 
       "size": 1 
     }, { 
      "name": "soy sauce", 
       "size": 1 
     }, { 
      "name": "wasabi", 
       "size": 1 
     }] 
    }] 
};} 

的数据可视化这样的:

enter image description here

这里是jsfiddle

我想在主图表的右侧创建一个标签列表,其中包含在树叶中找到的所有值,但每个值只有一次。换句话说,它应该包含:

  • “芦笋”
  • “腊肉”
  • “香醋”

(就像所有的 “联盟”叶)

如何获得具有独特元素的数组?

(显示的标签是没有问题的,我曾经我有一个阵列)

干杯!

回答

1

所以,你可以非常容易地使用如IxJSlodashunderscore这样的库。

但是,这里有一种方法可以在没有外部依赖的情况下完成。

function flatMap (arr, selector) { 
    return Array.prototype.concat.apply([], arr.map(selector)); 
} 

var names = 
    flatMap(getData().children, function (x) { return x.children; }) 
    .map(function (x) { return x.name; }); 

var length = names.length; 
var namesAndCount = {}; 

for (var i = 0; i < length; i++) { 
    var name = names[i]; 
    namesAndCount[name] = namesAndCount[name] ? namesAndCount[name] + 1 : 1; 
} 

在这一点上,namesAndCount将类似于此:

{ 
    "fennel":3, 
    "garlic":5, 
    "lemon":9, 
    "onion":5, 
    ... 
} 
+1

这真的很酷(柜台)!谢谢! – VividD

2

很容易检索所有名称属性/属性。

var fishNames = nodes.map(function(x){return x.name}); 

要在javascript中获取数组的唯一值,请检查here

+0

不,这不遍历子节点。你必须走整个树。 – greim

+0

节点是他在脚本中使用的变量: 'var root = getData(), nodes = radialCluster.nodes(root),...' 你明白我的意思了吗? –

+0

假设'radialCluster.nodes(root)'返回一个扁平列表,那么是的。 – greim

1
var data = getData(); 
var namesObj = {}; // Put leaves into object first for uniqueness 
for(var c0 in data.children) 
    for(var c1 in data.children[c0].children) 
    namesObj[data.children[c0].children[c1].name] = 1; 

var names = []; // Then put unique leaves into an array 
for(var name in namesObj) names.push(name); 

names // ["fennel", "garlic", "lemon", "onion", "parsley", "pasta", "rice", "soup", "tomato", "bay", "chilli", "olive oil", "paprika", "pine nuts", "asparagus", "bacon", "butter", "cellery", "chives", "mozzarella", "shallot", "balsamic vinegar", "cream", "dill", "ham", "honey", "lime", "mild cheese", "miso", "potato", "sesame", "soy souce", "spinach", "thyme", "coriander", "curry", "ginger", "lobster", "soft cheese", "eggs", "mandarin", "mushrooms", "spring onion", "courgette", "cumin", "peper", "rocket", "couscous", "cucumber", "pepper", "soya souce", "wasabi", "gream", "french beans", "leak", "sour cream", "strong cheese", "chili", "leek", "mayonnaise", "peas", "soy sauce"] 
1

你需要对你的对象做一个标准的树遍历。例如,假设你有一个在每个节点高层的回调函数:

walkObject(obj, function(obj, name, parent){ 
    /* obj === parent[name] */ 
}); 

所以我会做:

var names = {}; 
walkObject(nodes, function(obj, name, parent){ 
    if (name !== 'name') return; 
    names[obj] = true; 
}); 
var uniqueList = Object.keys(names); 

希望有所帮助。