代码之家  ›  专栏  ›  技术社区  ›  Datacrawler

对象的子数组(基于前2个值)缺少3+n值

  •  0
  • Datacrawler  · 技术社区  · 7 年前

    我有一个对象数组(用python术语表示的字典),其中 第一数值 _1111_ _2222_ 为了 二次价值 _first_ _second_ _third_ . 因此,在一个场景矩阵中,我们有6个案例。

    现在,我正在尝试为每个案例创建子数组,而不丢失其他对象的任何数据。在下面的输出中,如果我关注第一个场景( 1111 第1阶段 )时,我缺少数据 三值 VVV .

    有没有一种方法可以替代下面的reduce函数,或者我必须从一个完全不同的心态开始?(在这种情况下,我将不会合计这些数字)。

    var json_data = {"headers":["FirstValue","SecondValue","ThirdValue","FourthValue","FifthValue","NumberOne","NumberTwo"],"rows":[["_2222_","_first_","CPV","unknown","_2222_",92310.8671,5226.386074028007],["_2222_","_first_","WWW","known","_2222_",92310.8671,5226.386074028007],["_2222_","_second_","VVV","unknown","_2222_",92310.8671,null],["_2222_","_third_","VVV","unknown","_2222_",92310.8671,5226.386074028007],["_1111_","_first_","VVV","unknown","random",197977.2658,36169.2693355163],["_1111_","_first_","WWW","unknown","random",197977.2658,36169.2693355163],["_1111_","_second_","VVV","unknown","random",197977.2658,36169.2693355163],["_1111_","_third_","WWW","display","random",26536.9836,1957.2823939366558]]};
     
    var dataRows = json_data.rows;
    var dataHeaders = json_data.headers;
    var json =[];
    
    //Convert JSON to dictionary
    for (i = 0; i < dataRows.length; i++) 
    {
      var object = {};
      for (j = 0; j < dataHeaders.length; j++) 
      {  
        object[dataHeaders[j]] = dataRows[i][j];
      }
      json.push(object);
    }
    
    var res = json.reduce((r, e) => {
      let {SecondValue, FirstValue} = e;
      r[FirstValue] = r[FirstValue] || {}
      r[FirstValue][SecondValue] = r[FirstValue][SecondValue] || {}
      r[FirstValue][SecondValue] = r[FirstValue][SecondValue] || {}
      Object.assign(r[FirstValue][SecondValue], e);
      return r;
    }, {})
    
    var array = Object.values(res).map(Object.values)
    
    //Print the _1111_ branch
    if("_1111_" in res){
    	var _1111_ = res._1111_;
    }
    
        //Print the _1111_ branch
        if("_first_" in _1111_){
          var _first_ = _1111_._first_;
          document.getElementById("one").innerHTML = JSON.stringify(_first_, null, 2);
        }
    /*   
         if("_second_" in _1111_){
          var _second_ = _1111_._second_;
          document.getElementById("two").innerHTML = JSON.stringify(_second_, null, 2);
        }   
    
        if("_third_" in _1111_){
          var _third_ = _1111_._third_;
          document.getElementById("three").innerHTML = JSON.stringify(_third_, null, 2);
        }
    */
    /*
    //Print the _2222_ branch
    if("_2222_" in res){
    	var _2222_ = res._2222_;
    } 
    
        //Print the _2222_ branch
        if("_first_" in _2222_){
          var _first_ = _2222_._first_;
          document.getElementById("four").innerHTML = JSON.stringify(_first_, null, 2);
        }
    
        if("_second_" in _2222_){
          var _second_ = _2222_._second_;
          document.getElementById("five").innerHTML = JSON.stringify(_second_, null, 2);
        }
    
        if("_third_" in _2222_){
          var _third_ = _2222_._third_;
          document.getElementById("six").innerHTML = JSON.stringify(_third_, null, 2);
        }
    */
    <h3>_1111_ - _first_</h3>
    <div style="background:grey;" id="one"></div>
    <!--
    <h3>_1111_ - _second_</h3>
    <div style="background:green;" id="two"></div>
    <h3>_1111_ - _third_</h3>
    <div style="background:grey;" id="three"></div>
    <h3>_2222_ - _first_</h3>
    <div style="background:green;" id="four"></div>
    <h3>_2222_ - _second_</h3>
    <div style="background:grey;" id="five"></div>
    <h3>_2222_ - _third_</h3>
    <div style="background:green;" id="six"></div>
    -->

    PS:我保留了未注释的代码,因为这不是最终版本。重复的代码可能会被替换。

    2 回复  |  直到 7 年前
        1
  •  0
  •   Pinke Helga    7 年前

    我假设您打算在这个结构中获得输出:

    const json_data =
    {
      "headers":
        [
          "FirstValue",
          "SecondValue",
          "ThirdValue",
          "FourthValue",
          "FifthValue",
          "NumberOne",
          "NumberTwo"
        ],
    
      "rows":
        [
          [
            "_2222_",
            "_first_",
            "CPV",
            "unknown",
            "_2222_",
            92310.8671,
            5226.386074028007
          ],
          [
            "_2222_",
            "_first_",
            "WWW",
            "known",
            "_2222_",
            92310.8671,
            5226.386074028007
          ],
          [
            "_2222_",
            "_second_",
            "VVV",
            "unknown",
            "_2222_",
            92310.8671,
            null
          ],
          [
            "_2222_",
            "_third_",
            "VVV",
            "unknown",
            "_2222_",
            92310.8671,
            5226.386074028007
          ],
          [
            "_1111_",
            "_first_",
            "VVV",
            "unknown",
            "random",
            197977.2658,
            36169.2693355163
          ],
          [
            "_1111_",
            "_first_",
            "WWW",
            "unknown",
            "random",
            197977.2658,
            36169.2693355163
          ],
          [
            "_1111_",
            "_second_",
            "VVV",
            "unknown",
            "random",
            197977.2658,
            36169.2693355163
          ],
          [
            "_1111_",
            "_third_",
            "WWW",
            "display",
            "random",
            26536.9836,
            1957.2823939366558
          ]
        ]
    };
    
    
    // convert into array of objects [{FirstValue: 'abc', SecondValue: 'abc', ...}, ...]
    let converted  = json_data.rows.map(e => e.reduce( (accumulated, val, idx) => ({...accumulated, [json_data.headers[idx]]: val}), {} ) );
    // console.log('CONVERTED\n', converted);
    
    
    // to get an ordered and filtered output, let's do some stuff...
    
    const ordinal  = ['_first_', '_second_', '_third_'];
    
    // get an ordered unique array of the first two fields of each row, e.g. [['_1111_', '_first_'], ...]
    //   using a Set of JSON-Strings converted back to an array.
    let   unique01 = Array.from( new Set(json_data.rows.map((val, i) => JSON.stringify(val.slice(0,2)))) )
          .map(JSON.parse)
          // order by first field, then by second field
          .sort( (e1,e2) =>  e2[0] !== e1[0] ? e2[0] < e1[0] : ordinal.indexOf(e2[1]) < ordinal.indexOf(e1[1]) )
    ;
    // console.log('UNIQUE\n', unique01);
    
    let e = document.getElementById('data-container');
    
    // output filtered data sets as JSON
    for(let v of unique01)
      e.insertAdjacentHTML('beforeend',
        `    <h1>${v.join(' - ')}</h1>${converted.filter( e => e.FirstValue === v[0] && e.SecondValue === v[1] )
                                                 .reduce( (aggregated,o)=>`${aggregated}
    <div>${JSON.stringify(o)}</div>`
                                                          , '')
                                       }
    ` );
    <div id="data-container"></div>
        2
  •  0
  •   trincot    7 年前

    Object.assign(r[FirstValue][SecondValue], e) 您覆盖了 ThirdValue 新的属性 e . 如果需要同时保留这两个值,那么最好按FirstValue和SecondValue的组合使用数组:

    let {SecondValue, FirstValue} = e;
    r[FirstValue] = r[FirstValue] || {};
    r[FirstValue][SecondValue] = r[FirstValue][SecondValue] || [];  
    //                                                         ^^
    r[FirstValue][SecondValue].push(e);
    //                         ^^^^^^^
    return r;
    

    然后,您将需要使处理的其余部分适应这个修改过的数据结构。