【问题标题】:Rearrange javascript array重新排列 JavaScript 数组
【发布时间】:2020-08-12 13:52:36
【问题描述】:

如何以上述格式重新排列数据。我必须重新格式化数组并制作新的:

[
   {
      "cost":"1.3947648891000006",
      "start_date":"2020-06-10",
      "account":"1"
   },
   {
      "cost":"1.4069091170999999",
      "start_date":"2020-06-11",
      "account":"1"
   },
   {
      "cost":"1.401164025099997",
      "start_date":"2020-06-11",
      "account":"2"
   },
   {
      "cost":"2.50928182113",
      "start_date":"2020-06-12",
      "account":"2"
   }
]

到:

[
   {
      "start_date":"2020-06-10",
      "account_1_cost":"1.3947648891000006"
   },
   {
      "start_date":"2020-06-11",
      "account_1_cost":"1.4069091170999999",
      "account_2_cost":"1.401164025099997"
   },
   {
      "start_date":"2020-06-12",
      "account_2_cost":"2.50928182113"
   }
]

reduce函数和map函数我都试过了,没用。

【问题讨论】:

  • 所以您想通过start_date 安排这些帐户?那么,为什么不使用以日期为键的字典而不是数组呢? IE。 - {'2020-06-10' : (...), '2020-06-11': (...)}
  • 将数组对象解构为新对象数组。

标签: javascript arrays json sorting


【解决方案1】:

只需使用 array.reduce

const arr = 
  [ { cost: '1.3947648891000006', start_date: '2020-06-10', account: '1' } 
  , { cost: '1.4069091170999999', start_date: '2020-06-11', account: '1' } 
  , { cost: '1.401164025099997',  start_date: '2020-06-11', account: '2' } 
  , { cost: '2.50928182113',      start_date: '2020-06-12', account: '2' } 
  ] 

const res = 
  arr.reduce((acc,{cost, start_date, account})=>
    {
    let el = acc.find(x=>x.start_date===start_date)
    if (!el) acc.push(el = { start_date })
    el[`account_${account}_cost`] = cost
    return acc
    },[])

console.log( res ) 
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案2】:

    您可以分两步执行此操作,首先使用reducestart_date 分组,然后将其映射回数组:

    var input = [{"cost":"1.3947648891000006","start_date":"2020-06-10","account":"1"},{"cost":"1.4069091170999999","start_date":"2020-06-11","account":"1"},{"cost":"1.401164025099997","start_date":"2020-06-11","account":"2"},{"cost":"2.50928182113","start_date":"2020-06-12","account":"2"}];
    
    var grouped = input.reduce( (acc,i) => {
       if(acc.hasOwnProperty(i.start_date))
          acc[i.start_date].push(i);
        else
           acc[i.start_date] = [i];
        return acc;
    },{});
    
    var result = Object.entries(grouped).map( entry => {
       var [key,value] = entry;
       var obj = {start_date:key};
       for(var i=0;i<value.length;i++)
           obj[`account_${value[i].account}_cost`] = value[i].cost;
        return obj;
    });
    
    console.log(result);

    【讨论】:

      【解决方案3】:

      这是实现所需输出的简单方法。 只需创建一个start_date 的字典,然后继续将account_i_cost 添加到带有接收日期的字典中。最后,获取字典的所有值。

      var arr = [{"cost":"1.3947648891000006","start_date":"2020-06-10","account":"1"},{"cost":"1.4069091170999999","start_date":"2020-06-11","account":"1"},{"cost":"1.401164025099997","start_date":"2020-06-11","account":"2"},{"cost":"2.50928182113","start_date":"2020-06-12","account":"2"}];
      
      let objMap={}
      arr.forEach(obj=>{
      let field=`account_${obj.account}_cost`
      objMap[obj.start_date]=objMap[obj.start_date]?{...objMap[obj.start_date],[field]:obj.cost}:{
            "start_date":obj.start_date,
            [field]:obj.cost
         }
      })
      
      let result=Object.values(objMap)
      console.log(result)

      【讨论】:

        【解决方案4】:

        在这种情况下,正确的工具是Array.prototype.reduce()

        reduce() 方法对数组的每个元素执行(您提供的)reducer 函数,从而产生单个输出值。


        查看 cmets:

        var account_data = [
           {
              "cost":"1.3947648891000006",
              "start_date":"2020-06-10",
              "account":"1"
           },
           {
              "cost":"1.4069091170999999",
              "start_date":"2020-06-11",
              "account":"1"
           },
           {
              "cost":"1.401164025099997",
              "start_date":"2020-06-11",
              "account":"2"
           },
           {
              "cost":"2.50928182113",
              "start_date":"2020-06-12",
              "account":"2"
           }
        ];
        
        var refactored = account_data.reduce(function(new_object, current_item){
        
          // Get the essential information from the current item
          let {start_date, cost} = current_item;
          let cost_key = `account_${current_item.account}_cost`;
          
          // If there isn't a key for this date, create it
          if(!new_object[start_date]){
            new_object[start_date] = {start_date};
          }
          
          // Add the relevant info for the current date
          new_object[start_date][cost_key] = cost;
          return new_object;
        }, {});
        
        // Flatten it into an array
        refactored = Object.values(refactored);
        
        console.log(refactored);

        【讨论】:

          【解决方案5】:

          我会强烈建议不要指望一个数组,而是有一个以日期为键的字典。

          然后这段代码:

          // list = (...)
          list.reduce((prev, curr) => {
            if (!prev.hasOwnProperty(curr.start_date)) {
              prev[curr.start_date] = {};
            }
            prev[curr.start_date][`account_${curr.account}_cost`] = curr.cost;
            return prev;
          }, {})
          

          会给你这个结果:

          {
            "2020-06-10":{
              "account_1_cost":"1.3947648891000006"
            },
            "2020-06-11":{
              "account_1_cost":"1.4069091170999999",
              "account_2_cost":"1.401164025099997"
            },
            "2020-06-12":{
              "account_2_cost":"2.50928182113"
            }
          }
          

          但如果你真的想要它,试试这个:

          list.reduce((prev, curr) => {
            let elemWithDate = prev.find(el => el['start_date'] === curr['start_date']);
            if (!elemWithDate) {
              prev.push({'start_date': curr['start_date']});
              elemWithDate = prev[prev.length - 1];
            }
            elemWithDate[`account_${curr.account}_cost`] = curr.cost;
            return prev;
          }, []);
          

          【讨论】:

            【解决方案6】:

            在数组上使用 foreach 并查看哈希图中是否有该对象日期的条目。如果是这样,则不仅仅是将新属性 account_x_cost 添加到结果数组的相应元素(通过哈希中的索引)。否则,在结果数组中为此对象创建一个新条目,并将日期作为索引添加到哈希中。

            let arr = [ 
                { "cost": "1.3947648891000006", "start_date": "2020-06-10", "account": "1" }, 
                { "cost": "1.4069091170999999", "start_date": "2020-06-11", "account": "1" }, 
                { "cost": "1.401164025099997", "start_date": "2020-06-11", "account": "2" }, 
                { "cost": "2.50928182113", "start_date": "2020-06-12", "account": "2" }
            ];
            
            let result = [];
            let hash = [];
            
            arr.forEach(obj => {
            let index = hash.indexOf(obj.start_date);
                if (index==-1) {
                    result.push({start_date: obj.start_date, ['account' + obj.account + '_cost']: obj.cost});
                    hash.push(obj.start_date);
                } else {
                    result[index]['account' + obj.account + '_cost'] = obj.cost;
                }
            });
            console.log(result);

            【讨论】:

            • 这不是这家伙想要的。检查他的结果 - 他有 3 个项目,而不是 4 个
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-09-17
            • 2012-08-11
            • 2016-08-24
            • 1970-01-01
            相关资源
            最近更新 更多