【问题标题】:javascript, convert an array of objects to an array of arrays verticallyjavascript,将对象数组垂直转换为数组数组
【发布时间】:2021-05-30 11:17:52
【问题描述】:

我有一个已使用d3.csv 成功读取的 CSV 文件。结果是一个 JSON 文件,其中每一行由一个数组元素组成,每个数组元素是一个对象,其键/值对与列标题匹配。

我需要这种“垂直”格式,作为数组数组,其中每个内部数组由每个对象的值组成。

这是一个在 Node 中运行的示例:

> a = new Array();
[]
> a.push({"b":2, "c": 4, "d":6, "e": 8});
1
> a.push({"b":3, "c": 6, "d":9, "e": 12});
2
> a.push({"b":4, "c": 8, "d":12, "e": 16});
3
> a.push({"b":5, "c": 10, "d":15, "e": 20});
4
> a
[
  { b: 2, c: 4, d: 6, e: 8 },
  { b: 3, c: 6, d: 9, e: 12 },
  { b: 4, c: 8, d: 12, e: 16 },
  { b: 5, c: 10, d: 15, e: 20 }
]
> x = [[2,3,4,5],[4,6,8,10],[6,9,12,15],[8,12,16,20]]
[ [ 2, 3, 4, 5 ], [ 4, 6, 8, 10 ], [ 6, 9, 12, 15 ], [ 8, 12, 16, 20 ] ]
> x
[ 
  [ 2, 3, 4, 5 ], 
  [ 4, 6, 8, 10 ], 
  [ 6, 9, 12, 15 ], 
  [ 8, 12, 16, 20 ] 
]
>

这里,[a] 代表我拥有的对象数组,而[x] 代表我想要拥有的数组。

我的数据文件很宽,有很多列。我尝试了几种玩具解决方案,我可以遍历数组,选择每个元素,然后遍历每个元素并选择每个键,获取值,然后将其推送到新数组。然而,这是令人讨厌的并且很容易被打破。肯定有更好的方法。

如果我有一个列表列表,我可以翻转行和列。不幸的是,我有一个对象列表,请使用D3.csv() 阅读。

我的主要语言是(注意,曾经是)Perl,Perl-ish 解决方案对我来说很自然。我当前的应用程序在浏览器中运行客户端,我需要 JavaScript 中的客户端解决方案。

【问题讨论】:

    标签: javascript json d3.js


    【解决方案1】:

    我喜欢@pilchard 的d3 不可知论者的回答;但如果您对d3 驱动的答案感兴趣,您可以在数组数组上使用d3.transpose,并使用Object.values 删除对象的键的预处理步骤:

    const a = [
      { b: 2, c: 4, d: 6, e: 8 },
      { b: 3, c: 6, d: 9, e: 12 },
      { b: 4, c: 8, d: 12, e: 16 },
      { b: 5, c: 10, d: 15, e: 20 }
    ]
    
    const x = d3.transpose(a.map(o => Object.values(o)));
    
    console.log(x);
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.5.0/d3.min.js"></script>

    【讨论】:

      【解决方案2】:

      您可以通过多种方式实现此目的,但由于您的源数组中的所有对象似乎都具有相同的属性,因此最直接的可能是嵌套的map() 调用。外部map() 调用数组第一个元素的Object.keys(),内部map() 使用源数组中每个对象的每个迭代键。

      const a = [{ b: 2, c: 4, d: 6, e: 8 }, { b: 3, c: 6, d: 9, e: 12 }, { b: 4, c: 8, d: 12, e: 16 }, { b: 5, c: 10, d: 15, e: 20 }];
      
      const result = Object.keys(a[0]).map(key => a.map(o => o[key]));
      
      console.log(result);

      如果对象具有不同的属性,您可以使用reduce() 调用来累积相似属性的所有值。

      const a = [{ b: 2, c: 4, d: 6, e: 8 }, { b: 3, c: 6, d: 9, e: 12 }, { b: 4, c: 8, d: 12, e: 16 }, { b: 5, c: 10, d: 15, e: 20 }];
      
      const result = Object.values(
        a.reduce((acc, obj) => {
          Object.keys(obj).forEach(key =>
            (acc[key] ??= []).push(obj[key]));
      
          return acc;
        }, {}));
      
      console.log(result);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-22
        • 2021-01-07
        • 1970-01-01
        • 1970-01-01
        • 2012-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多