【问题标题】:Pivot/Transform json data columns to create new rows in javascript透视/转换 json 数据列以在 javascript 中创建新行
【发布时间】:2021-04-06 13:23:33
【问题描述】:

我有一个json 文件,格式如下:

const data = [
   {category: "A", country: "UK", name: "United Kingdom", country_id: "01", 2015: 5, 2016: 56, 2017: 10},
   {category: "B", country: "UK", name: "United Kingdom", country_id: "01", 2015: 4, 2016: 10, 2017: 10},
   {category: "C", country: "UK", name: "United Kingdom", country_id: "01", 2015: 10, 2016: 7, 2017: 45},
   {category: "A", country: "PO", name: "Poland", country_id: "02", 2015: 9, 2016: 14, 2017: 10},
   {category: "B", country: "PO", name: "Poland", country_id: "02", 2015: 10, 2016: 40, 2017: 0},
   {category: "C", country: "PO", name: "Poland", country_id: "02", 2015: 60, 2016: 30, 2017: 74},
   {category: "A", country: "CZ", name: "Czech Republic", country_id: "03", 2015: 30, 2016: 20, 2017: 10},
   {category: "B", country: "CZ", name: "Czech Republic", country_id: "03", 2015: 15, 2016: 28, 2017: 1},
   {category: "C", country: "CZ", name: "Czech Republic", country_id: "03", 2015: 16, 2016: 10, 2017: 2}
  ]

并且我想旋转数据以获得以下格式:

  • 201520162017 移动到名为year 的属性中
  • 从包含不同值的category 属性值创建abc 属性。
  • 每个国家和年份都有一个行/对象以及我想保留的任何其他序数类别。
const data = [
   {country: "UK", name: "United Kingdom", country_id: "01", year: "2015", "a": 5 , "b": 4, "c": 10},
   {country: "UK", name: "United Kingdom", country_id: "01", year: "2016", "a": 56 , "b": 10, "c": 7},
   {country: "UK", name: "United Kingdom", country_id: "01", year: "2017", "a": 10 , "b": 10, "c": 45},
   {country: "PO", name: "Poland", country_id: "02", year: "2015", "a": 9 , "b": 10, "c": 80},
   {country: "PO", name: "Poland", country_id: "02", year: "2016", "a": 14 , "b": 40, "c": 30},
   {country: "PO", name: "Poland", country_id: "02", year: "2017", "a": 10 , "b": 0, "c": 74},
   {country: "CZ", name: "Czech Republic", country_id: "03", year: "2015", "a": 30 , "b": 15, "c": 16},
   {country: "CZ", name: "Czech Republic", country_id: "03", year: "2016", "a": 20 , "b": 28, "c": 1},
   {country: "CZ", name: "Czech Republic", country_id: "03", year: "2017", "a": 10 , "b": 1, "c": 2}

我尝试在 map 方法中编写 for 循环,但无法创建 abc 属性。

【问题讨论】:

    标签: javascript json data-cleaning data-wrangling


    【解决方案1】:

    旋转是在注释为 'Rotation' 的 3 行上完成的

    为了能够做到这一点,我们需要能够访问原始数据集的多行。这里的策略使我们能够做到这一点。

    第 1 步。获取唯一国家/地区 ID、年份和类别的列表

    有几种方法可以做到这一点,我已经展示了最容易理解的方法,即转换为Set(它会自动删除重复项),然后再转换回数组以方便使用。

    步骤 2. 从一个简单的数组移动到一个对象

    行不再是简单地按 0...8 的顺序排列,我们现在将它们放在 3x3 网格中,可按国家和类别进行寻址。

    步骤 3. 构建所需的输出

    现在,在每个国家/地区,我们可以通过从原始数据的三个不同类别中“提取”今年的值来提取所选年份的所有数据。

    const data = [
       {category: "A", country: "UK", name: "United Kingdom", country_id: "01", 2015: 5, 2016: 56, 2017: 10},
       {category: "B", country: "UK", name: "United Kingdom", country_id: "01", 2015: 4, 2016: 10, 2017: 10},
       {category: "C", country: "UK", name: "United Kingdom", country_id: "01", 2015: 10, 2016: 7, 2017: 45},
       {category: "A", country: "PO", name: "Poland", country_id: "02", 2015: 9, 2016: 14, 2017: 10},
       {category: "B", country: "PO", name: "Poland", country_id: "02", 2015: 10, 2016: 40, 2017: 0},
       {category: "C", country: "PO", name: "Poland", country_id: "02", 2015: 60, 2016: 30, 2017: 74},
       {category: "A", country: "CZ", name: "Czech Republic", country_id: "03", 2015: 30, 2016: 20, 2017: 10},
       {category: "B", country: "CZ", name: "Czech Republic", country_id: "03", 2015: 15, 2016: 28, 2017: 1},
       {category: "C", country: "CZ", name: "Czech Republic", country_id: "03", 2015: 16, 2016: 10, 2017: 2}
      ]
    
    
    // Step 1. Extract the unique country_id, category Ids and years
    
    const country_ids = Array(...new Set(data.map((x) => x.country_id)));
    const categories = Array(...new Set(data.map((x) => x.category)));
    const years = ["2015","2016","2017"];
    
    // Step 2. Convert the source data into an object so that you can conveniently read off particular rows, in terms of COUNTRY_ID and CATEGORY
    
    const sourceRows = {};
    data.forEach((row) => {
      if (!sourceRows[row.country_id]) {
        sourceRows[row.country_id] = {};
      }
      sourceRows[row.country_id][row.category] = row;
    });
    
    // You can visualise the output here with this, if you want:
    //     console.log(sourceRows)
    
    
    // Step 3. Create destination array, and poke a row into it for each country & year.
    
    const destination = [];
    country_ids.forEach((country_id) => {
      years.forEach((year) => {
        const sourceRow = sourceRows[country_id][categories[0]];
        const destRow = {
          country_id: country_id,
          name: sourceRow.name,
          country: sourceRow.country,
          year: year,
          a: sourceRows[country_id]["A"][year], // Rotation
          b: sourceRows[country_id]["B"][year], // Rotation
          c: sourceRows[country_id]["C"][year]  // Rotation
        };
        destination.push(destRow);
      });
    });
    
    console.log(destination);

    【讨论】:

      【解决方案2】:

      不是最好的解决方案,但这是可行的。在 and,我为重复项做了一个解决方法。如果其他年份有新数据,您可以使用 ...rest 参数来初始化年份数组。

      let newData = [];
      let countries = data.map(({country})=> country)
      let categories = data.map(({category})=> category)
      let years = [2015,2016,2017];
      
      countries.forEach(country => {
          let countryData = data.filter(({country:c}) => c==country);
          let yearData = {2015:{},2016:{},2017:{}};
          years.forEach(year => {
              categories.forEach(category => {
                  yearData[year][category] = countryData.find(({category:cat}) => cat==category)[year]
             })
         })
         let {name,country_id}= data.find(({country:c}) => c == country);
      
         Object.entries(yearData).forEach(([year,categories]) => {
              newData.push({country,name,country_id,year, ...categories})
         })
         newData = newData.filter((data,i) => i%9<3)
         console.log(newData)
      })
      

      【讨论】:

        猜你喜欢
        • 2021-10-25
        • 1970-01-01
        • 1970-01-01
        • 2021-12-27
        • 2012-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多