【问题标题】:Avoiding nesting maps when "pivoting" multidimensional array“旋转”多维数组时避免嵌套映射
【发布时间】:2017-11-07 22:55:20
【问题描述】:

我有格式的数据

[
  {
    "timeline_map": {
      "2017-05-06": 770,
      "2017-05-07": 760,
      "2017-05-08": 1250
         ...
    }
  },
  {
    "timeline_map": {
      "2017-05-06": 590,
      "2017-05-07": 210,
      "2017-05-08": 300
         ...
    }
  },
  {
    "timeline_map": {
      "2017-05-06": 890,
      "2017-05-07": 2200,
      "2017-05-08": 1032
         ...
    }
  }
]

为了在谷歌图表中使用,我需要更改格式

[
  ["2017-05-06", 770, 590, 890, ...],
  ["2017-05-07", 760, 210, 2200, ...],
  ["2017-05-08", 1250, 300, 1032, ...]
]

我写了以下内容来进行转换

let mapped = _.map(
  chartData.results[0].timeline_map, (timestampVal, timestampKey) => (
  [timestampKey].concat(
    _.map(
      chartData.results, lineData => (
        lineData.timeline_map[timestampKey]
        )
      )
    )
  )
)

这行得通,但我认为嵌套maps 不是一个好主意,因为它将如何增加被映射数组长度的平方的循环量。这里有没有更好的方法来达到预期的结果。

JSBIN

【问题讨论】:

  • ["2017-05-06": 770, 590, 890, ...] 这不是有效的 JS。 [["2017-05-06", ...], ["2017-05-07", ...]]{"2017-05-06": [...], "2017-05-07": [...]}。是哪一个?
  • @Thomas 这只是一个省略号,表示还有更多日期。链接的 JSBIN 没有类似的伪元素
  • 我说的不是省略号,我说的是:
  • @Thomas 啊。哎呀。已更正。谢谢!
  • 一维对象数组。

标签: javascript arrays data-structures functional-programming lodash


【解决方案1】:

您可以在哈希表上使用闭包并将值相应地分配给日期键。

var data = [{ timeline_map: { "2017-05-06": 770, "2017-05-07": 760, "2017-05-08": 1250 } }, { timeline_map: { "2017-05-06": 590, "2017-05-07": 210, "2017-05-08": 300 } }, { timeline_map: { "2017-05-06": 890, "2017-05-07": 2200, "2017-05-08": 1032 } }],
    grouped = data.reduce(function (hash) {
        return function (r, o) {
            Object.keys(o.timeline_map).forEach(function (k) {
                if (!hash[k]) {
                    hash[k] = [k];
                    r.push(hash[k]);
                }
                hash[k].push(o.timeline_map[k]);
            });
            return r;
        };
    }(Object.create(null)), []);

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

【讨论】:

  • 这是正确的方法,但只需要更进一步即可获得所需的结果。
  • @Redu,你知道想要的结果吗? o_O
  • 参数由reduce方法提供。
  • 这些? (Object.create(null)), [])?
  • Object.create(null) 在闭包中初始化hash。空数组是结果数组的起始值。
【解决方案2】:

使用_.mergeWith() 合并对象,然后将_.map() 生成的对象合并到数组数组中:

const arr = [{
    "timeline_map": {
      "2017-05-06": 770,
      "2017-05-07": 760,
      "2017-05-08": 1250
    }
  },
  {
    "timeline_map": {
      "2017-05-06": 590,
      "2017-05-07": 210,
      "2017-05-08": 300
    }
  },
  {
    "timeline_map": {
      "2017-05-06": 890,
      "2017-05-07": 2200,
      "2017-05-08": 1032
    }
  }
];

const result = _.map(_.mergeWith({}, ...arr, (o1, o2) => {
  if(Array.isArray(o1)) {
    o1.push(o2)
    return o1;
  }
  
  if(_.isNumber(o2)) {
    return [o2];
  }
}).timeline_map, (v, k) => [k, ...v]);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

【讨论】:

  • +1 以获得干净的解决方案。只是指出扩展运算符将在数组达到一定大小后开始给出调用堆栈溢出错误。
猜你喜欢
  • 1970-01-01
  • 2019-04-29
  • 2019-08-13
  • 1970-01-01
  • 2013-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-08
相关资源
最近更新 更多