2013-12-09 42 views
0

我正在做一些可视化,需要合并某些json条目。用d3合并json条目

问题是,被调用的json文件有点搞砸了。某些条目需要合并,其他条目应保持不变。

的JSON我得到的是这样的:

[ 
    { 
    "label": "de", 
    "visits": 80, 
    }, 
    { 
    "label": "fr", 
    "visits": 80, 
    }, 
    { 
    "label": "/de", 
    "visits": 80, 
    }, 
    { 
    "label": "/fr", 
    "visits": 80, 
    }, 
    { 
    "label": "Aktuell", 
    "visits": 80, 
    }, 
    { 
    "label": "fr/Aktuell", 
    "visits": 80, 
    }, 
    { 
    "label": "index", 
    "visits": 80, 
    } 
] 

我需要的是:

[ 
    { 
    "label": "de", 
    "visits": 160, 
    }, 
    { 
    "label": "fr", 
    "visits": 160, 
    }, 
    { 
    "label": "Aktuell", 
    "visits": 160, 
    }, 
    { 
    "label": "index", 
    "visits": 80, 
    } 
] 

与标签 “德” 的条目和 “/德” 以及 “FR”和“/ fr”或“fr/Aktuell”和“Aktuell”需要合并,而其他条目应像“索引”一样保持不变。

有没有办法使用d3来做到这一点? 我想只使用JavaScript我将不得不得到的JSON文件,然后搜索条目,创建一个新的条目,并加起来的数字,然后采取原来的JSON,删除这些条目,并添加新的条目......虽然我也不知道如何做到这一点。

而且这也不是最好的解决方案,因为我必须生成第二个对象,这个对象将不得不被处理并减慢整个系统。我们已经有性能问题,我不想创建新的瓶颈。

的另一个问题是,我需要能够延长应合并条目列表...

是否有这样做的一个快速简单的方式?

我知道这看起来像一个“嘿,我太懒惰了,为我做”后。 我可以向你保证它不是。这更像是一个“我google搜索,我读过,我试过,我发誓,我哭了,现在我要求专业人士帮忙”的帖子。

UPDATE:

我不希望过滤只是对 '/' 的最后一部分。这只是一个例子。过滤器更像是:将所有[en,EN,/ en,english,anglais]与标签en结合。还将所有[de,DE,/ de,deutsch,german]与标签de组合。保留所有未组合的其他人。

回答

1

的Javascript应该为这个已经足够了:

function clean(arr) { 
    var obj = {}; 
    // obj will contain a map with keys being 'label' and value being 'visits' 
    for (var i = 0; i < arr.length; i++) { 
     var labelParts = arr[i].label.split('/') 
     var label = labelParts[labelParts.length-1] 
     // Do a bit of filtering on the label 

     if(typeof obj[label]!=='undefined') { 
      obj[label] += arr[i].visits 
     } else { 
      obj[label] = arr[i].visits 
     } 
    } 
    return Object.keys(obj).map(function (key) { return {label:key,visits:obj[key]}; }); 
    // Re-create an array out of the object 
} 

我假设你想在后“/”的最后一部分过滤。

的jsfiddle:http://jsfiddle.net/4peN9/2/

+0

谢谢!唯一的问题是,我不想仅在'/'的最后部分进行过滤。这只是一个例子。过滤器更像是:将所有[en,EN,/ en,english,anglais]与标签en结合。还将所有[de,DE,/ de,deutsch,german]与标签de组合。保留所有未组合的其他人。 – k3njiy

+0

然后你只需要更新你想要的过滤部分。我想你可能需要收集你正在寻找的字符串。 –

1

我想看看D3的nest操作。指定合适的密钥和汇总函数以获得所需内容不应太难。东西的效果:

var cleanup = function(l) { 
    var i = l.indexOf("/"); 
    return i < 0 ? l : l.substring(i+1, l.length); 
}; 
var getVisits = function(d) { return d.visits; }; 
var sum = function(a, b) { return a + b; }; 

var nest = d3.nest() 
    .key(function(d) { return cleanup(d.label); }) 
    .rollup(function(a) { return a.map(getVisits).reduce(sum); }); 

的jsfiddle:http://jsfiddle.net/4peN9/3/

0

我现在写的一个比较难看,但功能的JavaScript脚本这一点。我相信它可以做得更有效率,但这对我来说应该是有效的。

它是这样的:

function clean(arr) 
    { 
    mrgLst = [ 
     { 
     "valid": "de", 
     "invalid": ["/de"] 
     }, 
     { 
     "valid": "fr", 
     "invalid": ["/fr"] 
     }, 
     { 
     "valid": "en", 
     "invalid": ["/en"] 
     }, 
     { 
     "valid": "it", 
     "invalid": ["/it"] 
     }, 
     { 
     "valid": "/index", 
     "invalid": ["/index.html"] 
     } 
    ] 

    var obj = []; 
    for (var i = 0; i < mrgLst.length; i++) 
    { 
     var valid = mrgLst[i].valid; 
     var invalid = mrgLst[i].invalid; 

     for (var j = 0; j < arr.length; j++) 
     { 
     var test0 = arr[j].label 
     if (test0 == valid) 
     { 
      var subObj = {}; 

      subObj["label"] = valid 
      subObj["visits"] = arr[j].visits 

      for (var k = 0; k < arr.length; k++) 
      {    
      var test1 = arr[k].label 
      for (x in invalid) 
      { 
       if (test1 == invalid[x]) 
       { 
       subObj["label"] = valid 
       subObj["visits"] += arr[k].visits 
       } 
      } 
      } 
     } 
     } 
     if (subObj != undefined) 
     { 
     obj.push(subObj) 
     } 

    } 

    for (var i = 0; i < arr.length; i++) 
    { 
     var original = arr[i] 
     var org = {} 
     var dont = false 

     for (var j = 0; j < mrgLst.length; j++) 
     { 
     var test0 = mrgLst[j].valid 
     var test1 = mrgLst[j].invalid 

     if (original.label == test0) 
     { 
      dont = true 
     } 
     for (x in test1) 
     { 
      if (original.label == test1[x]) 
      { 
      dont = true 
      } 
     } 
     } 

     if (dont == false) 
     { 
     org["label"] = original.label 
     org["visits"] = arr[i].visits 

     obj.push(org) 
     } 
    } 
    return obj 
    } 

正如对于有类似的问题任何人参考。与d3没有多大关系,但输出与d3一起使用...