下划线 - 使用_.map()

时间:2016-02-06 21:33:26

标签: javascript arrays underscore.js

我有一个多维的对象数组,我需要将其转换为不同的数组。我确信_.map()是我所需要的。之前没有使用它,我在遍历数组时无法提取正确的值。鉴于这个简化的例子:

[
   {
      "08/25/2015":[
         {
            "source":"someSource0",
            "name":"someName0",
            "stuff":"-6.728479",
            "stuffValue":"14.862200",
            "amount":"-100.00"
         },
         {
            "notNeeded0":-100,
            "subtotal":"-100.00"
         }
      ]
   },
   {
      "08/26/2015":[
         {
            "source":"someSource1",
            "name":"someName1",
            "stuff":"-9.496676",
            "stuffValue":"10.530000",
            "amount":"-100.00"
         },
         {
            "notNeeded0":-100,
            "subtotal":"-100.00"
         }
      ]
   },
   {
      "08/27/2015":[
         {
            "source":"someSource2",
            "name":"someName2",
            "stuff":"-9.469697",
            "stuffValue":"10.560000",
            "amount":"-100.00"
         },
         {
            "notNeeded0":-100,
            "subtotal":"-100.00"
         }
      ]
   },
   {
      "08/28/2015":[
         {
            "source":"someSource3",
            "name":"someName3",
            "stuff":"-1.731841",
            "stuffValue":"10.570000",
            "amount":"-18.24"
         },
         {
            "source":"someSource4",
            "name":"someName4",
            "stuff":"-2.628939",
            "stuffValue":"31.100000",
            "amount":"-81.76"
         },
         {
            "notNeeded0":-100,
            "subtotal":"-100.00"
         }
      ]
   },
   {
      "notNeeded1":-400,
      "notNeeded2":"-400.00"
   }
]

我需要将其转换为这样的结构:

[
   {
      "date":"08/27/2015",
      "detail":[
         {
            "source":"someSource2",
            "name":"someName2",
            "stuff":"-9.469697",
            "stuffValue":"10.560000",
            "amount":"-100.00",
            "subtotal":"-100.00"
         }
      ]
   },
   {
      "date":"08/28/2015",
      "detail":[
         {
            "source":"someSource3",
            "name":"someName3",
            "stuff":"-1.731841",
            "stuffValue":"10.570000",
            "amount":"-18.24",
            "subtotal":"-100.00"
         },
         {
            "source":"someSource4",
            "name":"someName4",
            "stuff":"-2.628939",
            "stuffValue":"31.100000",
            "amount":"-81.76",
            "subtotal":"-100.00"
         }
      ]
   }
]

如果需要,请随时提问。谢谢你的帮助。

编辑:此代码不适用于基于网络的使用。因此,不需要任何对Web和浏览器兼容性的引用。而且,我使用下划线库来简化循环等任务,使用纯JS可以变得非常难看。希望澄清意图。

2 个答案:

答案 0 :(得分:1)

使用内置.filter.map.splice

var modified = original.filter(function only_nested_arrays(obj) {
  var keys = Object.keys(obj)
  return keys.length === 1 && Array.isArray(obj[keys[0]])
}).map(function transform(obj) {
  var date = Object.keys(obj)[0],
      inner_array = obj[date],
      subtotal = inner_array.splice(-1)[0].subtotal
  inner_array.forEach(function(obj_inner) {
    obj_inner.subtotal = subtotal
  })
  return {date: date, detail: inner_array}
})

console.log(JSON.stringify(modified, null, 2))

但请注意浏览器兼容性(请参阅polyfill的链接以使其在IE8或更低版本上运行)。如果要测试,可以运行代码来警告结果:



"use strict"
var original = [
  {
    "08/25/2015":[
      {
        "source":"someSource0",
        "name":"someName0",
        "stuff":"-6.728479",
        "stuffValue":"14.862200",
        "amount":"-100.00"
      },
      {
        "notNeeded0":-100,
        "subtotal":"-100.00"
      }
    ]
  },
  {
    "08/26/2015":[
      {
        "source":"someSource1",
        "name":"someName1",
        "stuff":"-9.496676",
        "stuffValue":"10.530000",
        "amount":"-100.00"
      },
      {
        "notNeeded0":-100,
        "subtotal":"-100.00"
      }
    ]
  },
  {
    "08/27/2015":[
      {
        "source":"someSource2",
        "name":"someName2",
        "stuff":"-9.469697",
        "stuffValue":"10.560000",
        "amount":"-100.00"
      },
      {
        "notNeeded0":-100,
        "subtotal":"-100.00"
      }
    ]
  },
  {
    "08/28/2015":[
      {
        "source":"someSource3",
        "name":"someName3",
        "stuff":"-1.731841",
        "stuffValue":"10.570000",
        "amount":"-18.24"
      },
      {
        "source":"someSource4",
        "name":"someName4",
        "stuff":"-2.628939",
        "stuffValue":"31.100000",
        "amount":"-81.76"
      },
      {
        "notNeeded0":-100,
        "subtotal":"-100.00"
      }
    ]
  },
  {
    "notNeeded1":-400,
    "notNeeded2":"-400.00"
  }
]

var modified = original.filter(function only_nested_arrays(obj) {
  var keys = Object.keys(obj)
  return keys.length === 1 && Array.isArray(obj[keys[0]])
}).map(function transform(obj) {
  var date = Object.keys(obj)[0],
      inner_array = obj[date],
      subtotal = inner_array.splice(-1)[0].subtotal
  inner_array.forEach(function(obj_inner) {
    obj_inner.subtotal = subtotal
  })
  return {date: date, detail: inner_array}
})

alert(JSON.stringify(modified, null, 2))




答案 1 :(得分:0)

使用_.filter_.map& _.chain这就是它的样子。

var transformed = _.chain(data).filter(function (obj) {
    var keys = _.keys(obj);
    // only allow where obj has only one key & the value is an array
    // consider replacing this with a check to see if the key is a date which should be more appropriate
    return keys.length === 1 && _.isArray(obj[keys[0]]);
}).map(function (obj) {
    var date     = _.keys(obj)[0];
    var details  = obj[date];
    var subtotal = details.splice(-1)[0].subtotal; // get the last obj from array destructively
    details      = _.map(details, function (detail) {
        detail.subtotal = subtotal; // append the subtotal to all the remaining detail objects
        return detail
    });
    return {
        date   : date,
        details: details
    }
}).value();

我建议你使用Aprillion的答案中显示的原生函数,这样你就可以避免整个chain()&然后value()用于从包装对象中获取实际值。当需求稍微复杂时,您可以使用下划线。