【问题标题】:How to read a javascript array and reformat it as JSON objects?如何读取 javascript 数组并将其重新格式化为 JSON 对象?
【发布时间】:2018-07-05 19:31:34
【问题描述】:

我正在根据我给定的参数从 Google Analytics API 获取以下数据。这是一个 JavaScript 数组对象。

[ [ '201801', '(Other)', '129' ],
  [ '201801', 'Direct', '2236' ],
  [ '201801', 'Email', '2' ],
  [ '201801', 'Organic Search', '6263' ],
  [ '201801', 'Referral', '185' ],
  [ '201801', 'Social', '669' ],
  [ '201802', '(Other)', '371' ],
  [ '201802', 'Direct', '2037' ],
  [ '201802', 'Email', '3' ],
  [ '201802', 'Organic Search', '5790' ],
  [ '201802', 'Referral', '162' ],
  [ '201802', 'Social', '515' ],
  [ '201803', '(Other)', '213' ],
  [ '201803', 'Direct', '2465' ],
  [ '201803', 'Organic Search', '8596' ],
  [ '201803', 'Referral', '238' ],
  [ '201803', 'Social', '356' ],
  [ '201804', '(Other)', '65' ],
  [ '201804', 'Direct', '1872' ],
  [ '201804', 'Email', '1' ],
  [ '201804', 'Organic Search', '9275' ],
  [ '201804', 'Referral', '170' ],
  [ '201804', 'Social', '307' ],
  [ '201805', '(Other)', '35' ],
  [ '201805', 'Direct', '2429' ],
  [ '201805', 'Email', '2' ],
  [ '201805', 'Organic Search', '8995' ],
  [ '201805', 'Referral', '234' ],
  [ '201805', 'Social', '341' ],
  [ '201806', 'Direct', '51' ],
  [ '201806', 'Organic Search', '282' ],
  [ '201806', 'Referral', '1' ],
[ '201806', 'Social', '3' ] ]

如果不清楚,请查看此 GIST:https://gist.github.com/chanakaDe/3ad4e2a51c99386a2737b65a82f034b1

在这个数组中,你可以看到像这样的'201801'。这意味着 YEAR 是 2018 年,MONTH 是 1 日。它同样继续。

通常在某一特定月份,我们会获得 6 个值,例如 (Other) 、 Direct 、 Email 、 Organic Search 。推荐和社交。在这个数组中,同一日期重复 6 次。

我想做的是从中创建一个简单的 JSON 对象。这是我要创建的格式,以便在我的 AngularJS 前端显示所有这些数据。

[
    {
        "date" : "201801",
        "(Other)" : "129",
        "Direct" : "2236",
        "Email" : "2",
        "OrganicSearch" : "6263",
        "Referral" : "185",
        "Social" : "669"
    },
    {
        "date" : "201802",
        "(Other)" : "371",
        "Direct" : "2037",
        "Email" : "3",
        "OrganicSearch" : "5790",
        "Referral" : "162",
        "Social" : "515"
    }
]

我想要一个这样的 JSON 数组。我试图找到重复的值,然后尝试将它们合并到一个 JSON 对象中(如果附近的元素相同)。很多这样的尝试。但是还是不行。请各位,此刻真的很想得到你们的帮助。我不擅长数据分析和这类排序。请帮帮我。该项目使用 Node.js 8.10.0 完成。

【问题讨论】:

    标签: javascript arrays json node.js google-analytics


    【解决方案1】:

    您可以将日期作为哈希表的键并收集所有键值对。稍后仅获取对象数组的值。

    var array = [['201801', '(Other)', '129'], ['201801', 'Direct', '2236'], ['201801', 'Email', '2'], ['201801', 'Organic Search', '6263'], ['201801', 'Referral', '185'], ['201801', 'Social', '669'], ['201802', '(Other)', '371'], ['201802', 'Direct', '2037'], ['201802', 'Email', '3'], ['201802', 'Organic Search', '5790'], ['201802', 'Referral', '162'], ['201802', 'Social', '515'], ['201803', '(Other)', '213'], ['201803', 'Direct', '2465'], ['201803', 'Organic Search', '8596'], ['201803', 'Referral', '238'], ['201803', 'Social', '356'], ['201804', '(Other)', '65'], ['201804', 'Direct', '1872'], ['201804', 'Email', '1'], ['201804', 'Organic Search', '9275'], ['201804', 'Referral', '170'], ['201804', 'Social', '307'], ['201805', '(Other)', '35'], ['201805', 'Direct', '2429'], ['201805', 'Email', '2'], ['201805', 'Organic Search', '8995'], ['201805', 'Referral', '234'], ['201805', 'Social', '341'], ['201806', 'Direct', '51'], ['201806', 'Organic Search', '282'], ['201806', 'Referral', '1'], ['201806', 'Social', '3']],
        result = Object.values(
            array.reduce((r, [date, key, value]) => {
                r[date] = r[date] || { date };
                r[date][key] = value;
                return r;
            }, {})
        );
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

    • 感谢回答的小伙伴
    【解决方案2】:

    这里有一个可行的解决方案,而且很容易阅读。

    var example = [
      ['201801', '(Other)', '129'],
      ['201801', 'Direct', '2236'],
      ['201801', 'Email', '2'],
      ['201801', 'Organic Search', '6263'],
      ['201801', 'Referral', '185'],
      ['201801', 'Social', '669'],
      ['201802', '(Other)', '371'],
      ['201802', 'Direct', '2037'],
      ['201802', 'Email', '3'],
      ['201802', 'Organic Search', '5790'],
      ['201802', 'Referral', '162'],
      ['201802', 'Social', '515'],
      ['201803', '(Other)', '213'],
      ['201803', 'Direct', '2465'],
      ['201803', 'Organic Search', '8596'],
      ['201803', 'Referral', '238'],
      ['201803', 'Social', '356'],
      ['201804', '(Other)', '65'],
      ['201804', 'Direct', '1872'],
      ['201804', 'Email', '1'],
      ['201804', 'Organic Search', '9275'],
      ['201804', 'Referral', '170'],
      ['201804', 'Social', '307'],
      ['201805', '(Other)', '35'],
      ['201805', 'Direct', '2429'],
      ['201805', 'Email', '2'],
      ['201805', 'Organic Search', '8995'],
      ['201805', 'Referral', '234'],
      ['201805', 'Social', '341'],
      ['201806', 'Direct', '51'],
      ['201806', 'Organic Search', '282'],
      ['201806', 'Referral', '1'],
      ['201806', 'Social', '3']
    ]
    //using a forEach to map to object and then a map to map it into an array.
    var obj = {};
    example.forEach(item => {
      if (obj[item[0]]) {
        obj[item[0]][item[1]] = item[2]
      } else {
        obj[item[0]] = {};
        obj[item[0]]["date"] = item[0]
      }
    })
    
    var result = Object.keys(obj).map(k => obj[k])
    console.log(result)

    【讨论】:

    • 这是有效的,但缺少“(其他)”列。为什么是兄弟?
    【解决方案3】:

    这是获得所需输出的方法 -

    let data = [
      ['201801', '(Other)', '129'],
      ['201801', 'Direct', '2236'],
      ['201801', 'Email', '2'],
      ['201801', 'Organic Search', '6263'],
      ['201801', 'Referral', '185'],
      ['201801', 'Social', '669'],
      ['201802', '(Other)', '371'],
      ['201802', 'Direct', '2037'],
      ['201802', 'Email', '3'],
      ['201802', 'Organic Search', '5790'],
      ['201802', 'Referral', '162'],
      ['201802', 'Social', '515'],
      ['201803', '(Other)', '213'],
      ['201803', 'Direct', '2465'],
      ['201803', 'Organic Search', '8596'],
      ['201803', 'Referral', '238'],
      ['201803', 'Social', '356'],
      ['201804', '(Other)', '65'],
      ['201804', 'Direct', '1872'],
      ['201804', 'Email', '1'],
      ['201804', 'Organic Search', '9275'],
      ['201804', 'Referral', '170'],
      ['201804', 'Social', '307'],
      ['201805', '(Other)', '35'],
      ['201805', 'Direct', '2429'],
      ['201805', 'Email', '2'],
      ['201805', 'Organic Search', '8995'],
      ['201805', 'Referral', '234'],
      ['201805', 'Social', '341'],
      ['201806', 'Direct', '51'],
      ['201806', 'Organic Search', '282'],
      ['201806', 'Referral', '1'],
      ['201806', 'Social', '3']
    ];
    
    let output = {};
    data.map((value) => { if(!output[value[0]]) { output[value[0]] = {}; } output[value[0]][value[1]] = value[2]; })
    
    console.log(Object.keys(output).map(key => { output[key]["date"] = key; return output[key]; }));

    【讨论】:

    • 这是对map 的不当使用。 let output = {}; data.map(value => /* do something to output */) 更好地表达为let output = data.reduce((output, value) => /* do something to output and return it */, {})
    • 感谢 Vivek 的回答和努力
    • 我仍然对你是如何在一条信号线上做到这一点感到困惑 :-)
    • 使用这个:data.map((value) => { if(!output[value[0]]) { output[value[0]] = {}; } output[value[0 ]][value[1]] = value[2]; }) ---> 能否请您解释一下,如果您可以的话.... 抱歉问这个问题。我知道这太过分了。 :-)
    • @ChanakaDeSilva 因此,如果您查看它的输出,它将一次只使用数组中的一项 - ['201806', 'Social', '3'] 检查日期是否已在 output 中存在或不存在,如果存在则只需在对象中添加Social: 3,以201806 作为键。在第二条语句Object.keys... 中,它只需将键201806 添加到它自己的对象中,例如{ date:201806, Social: 3 }。希望这会有所帮助
    【解决方案4】:

    如果ary 是您的输入数组,应该这样做:

    const outputObj = ary.reduce((obj, subAry) => {
      const [date, key, val] = subAry 
      obj[date] = obj[date] || {}
      obj[date]['date'] = date
      obj[date][key] = val
      return obj
    }, {})
    
    console.log(Object.values(outputObj))
    

    【讨论】:

      【解决方案5】:

      使用reduce将输入数据按月份分组,键为日期,并将分组后的对象映射到所需的输出:

      const data = [ [ '201801', '(Other)', '129' ],
        [ '201801', 'Direct', '2236' ],
        [ '201801', 'Email', '2' ],
        [ '201801', 'Organic Search', '6263' ],
        [ '201801', 'Referral', '185' ],
        [ '201801', 'Social', '669' ],
        [ '201802', '(Other)', '371' ],
        [ '201802', 'Direct', '2037' ],
        [ '201802', 'Email', '3' ],
        [ '201802', 'Organic Search', '5790' ],
        [ '201802', 'Referral', '162' ],
        [ '201802', 'Social', '515' ],
        [ '201803', '(Other)', '213' ],
        [ '201803', 'Direct', '2465' ],
        [ '201803', 'Organic Search', '8596' ],
        [ '201803', 'Referral', '238' ],
        [ '201803', 'Social', '356' ],
        [ '201804', '(Other)', '65' ],
        [ '201804', 'Direct', '1872' ],
        [ '201804', 'Email', '1' ],
        [ '201804', 'Organic Search', '9275' ],
        [ '201804', 'Referral', '170' ],
        [ '201804', 'Social', '307' ],
        [ '201805', '(Other)', '35' ],
        [ '201805', 'Direct', '2429' ],
        [ '201805', 'Email', '2' ],
        [ '201805', 'Organic Search', '8995' ],
        [ '201805', 'Referral', '234' ],
        [ '201805', 'Social', '341' ],
        [ '201806', 'Direct', '51' ],
        [ '201806', 'Organic Search', '282' ],
        [ '201806', 'Referral', '1' ],
      [ '201806', 'Social', '3' ] ];
      
      const dataObj = data.reduce((all, [month, key, val]) => {
      
        if (!all.hasOwnProperty(month)) all[month] = {};
        all[month][key] = val;
        return all;
      
      }, {});
      
      const result = Object.keys(dataObj).map(k => Object.assign({}, dataObj[k], {date: k}))
      
      console.log(result);
      

      【讨论】:

        【解决方案6】:
        const input = [ 
          [ '201801', '(Other)', '129' ],
          [ '201801', 'Direct', '2236' ],
          [ '201801', 'Email', '2' ],
          [ '201801', 'Organic Search', '6263' ],
          [ '201801', 'Referral', '185' ],
          [ '201801', 'Social', '669' ],
          [ '201802', '(Other)', '371' ],
          [ '201802', 'Direct', '2037' ],
          [ '201802', 'Email', '3' ],
          [ '201802', 'Organic Search', '5790' ],
          [ '201802', 'Referral', '162' ],
          [ '201802', 'Social', '515' ],
          [ '201803', '(Other)', '213' ],
          [ '201803', 'Direct', '2465' ],
          [ '201803', 'Organic Search', '8596' ],
          [ '201803', 'Referral', '238' ],
          [ '201803', 'Social', '356' ],
          [ '201804', '(Other)', '65' ],
          [ '201804', 'Direct', '1872' ],
          [ '201804', 'Email', '1' ],
          [ '201804', 'Organic Search', '9275' ],
          [ '201804', 'Referral', '170' ],
          [ '201804', 'Social', '307' ],
          [ '201805', '(Other)', '35' ],
          [ '201805', 'Direct', '2429' ],
          [ '201805', 'Email', '2' ],
          [ '201805', 'Organic Search', '8995' ],
          [ '201805', 'Referral', '234' ],
          [ '201805', 'Social', '341' ],
          [ '201806', 'Direct', '51' ],
          [ '201806', 'Organic Search', '282' ],
          [ '201806', 'Referral', '1' ],
          [ '201806', 'Social', '3' ]
        ];
        
        let output = [];
        
        for (let i = 0; i < input.length; i++) {
            let index = output.findIndex(obj => obj.date === input[i][0]);
            if (index === -1) {
                index = output.length;
                output[index] = {date: input[i][0]};
            }
            output[index][input[i][1]] = input[i][2];
        }
        

        【讨论】:

          猜你喜欢
          • 2021-10-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-19
          • 2018-10-26
          • 2017-07-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多