使用 d3.groups 按多个键对对象数组进行分组

Group array of objects by multiple keys using d3.groups

我有这个数据集:

const data = [ 
  {animal: 'cat', name: 'mu', date: new Date(2020, 0, 1), status: -1},
  {animal: 'cat', name: 'muji', date: new Date(2021, 0, 1), status: 0},
  {animal: 'cat', name: 'mine', date: new Date(2021, 0, 1), status: 1},
  {animal: 'dog', name: 'fido', date: new Date(2021, 0, 1), status: 1}, 
  {animal: 'dog', name: 'fido2', date: new Date(2020, 0, 1), status: 1}, 
  {animal: 'dog', name: 'fido3', date: new Date(2021, 0, 1), status: 0}, 
  {animal: 'hamster', name: 'gerry', date: new Date(2019, 0, 1), status: 0}, 
  {animal: 't-rex', name: 'dino', date: new Date(2020, 0, 1), status: 0},
  {animal: 't-rex', name: 'sauro', date: new Date(2019, 0, 1), status: 0},
  {animal: 'sheep', name: 's', date: new Date(2019, 0, 1), status: 0}, 
  {animal: 'sheep', name: 'sss', date: new Date(2019, 0, 1), status: -1}, 
]

我想按 animalstatus 对它进行分组以获得如下内容:

const grouped = {
  cat: {
    -1: [{animal: 'cat', name: 'mu', date: new Date(2020, 0, 1), status: -1}],
    0: [{animal: 'cat', name: 'muji', date: new Date(2021, 0, 1), status: 0}]
    1: [{animal: 'cat', name: 'mine', date: new Date(2021, 0, 1), status: 1}]
  },
  dog: {
    0: [{animal: 'dog', name: 'fido3', date: new Date(2021, 0, 1), status: 0}],
    1: [
      {animal: 'dog', name: 'fido', date: new Date(2021, 0, 1), status: 1}, 
    {animal: 'dog', name: 'fido2', date: new Date(2020, 0, 1), status: 1}
    ]
  },
  hamster: {
    0: [{animal: 'hamster', name: 'gerry', date: new Date(2019, 0, 1), status: 0}],
  },
  't-rex': {
    0: [{animal: 't-rex', name: 'dino', date: new Date(2020, 0, 1), status: 0},
  {animal: 't-rex', name: 'sauro', date: new Date(2019, 0, 1), status: 0},],
  },
  sheep: {
    -1: [{animal: 'sheep', name: 'sss', date: new Date(2019, 0, 1), status: -1}],
    0: [{animal: 'sheep', name: 's', date: new Date(2019, 0, 1), status: 0}],
  }
}

我用d3.groups对数据进行分组:

const grouped = d3.groups(data, d => d.animal, d => d.status)
/*
[
  [
    'cat',
    [
      [
        -1,
        [
          {
            animal: 'cat',
            name: 'mu',
            date: 2019-12-31T23:00:00.000Z,
            status: -1
          }
        ]
      ],
      [
        0,
        [
          {
            animal: 'cat',
            name: 'muji',
            date: 2020-12-31T23:00:00.000Z,
            status: 0
          }
        ]
      ],
      [
        1,
        [
          {
            animal: 'cat',
            name: 'mine',
            date: 2020-12-31T23:00:00.000Z,
            status: 1
          }
        ]
      ]
    ]
  ],
  [
    'dog',
    [
      [
        1,
        [
          {
            animal: 'dog',
            name: 'fido',
            date: 2020-12-31T23:00:00.000Z,
            status: 1
          },
          {
            animal: 'dog',
            name: 'fido2',
            date: 2019-12-31T23:00:00.000Z,
            status: 1
          }
        ]
      ],
      [
        0,
        [
          {
            animal: 'dog',
            name: 'fido3',
            date: 2020-12-31T23:00:00.000Z,
            status: 0
          }
        ]
      ]
    ]
  ],
  [
    'hamster',
    [
      [
        0,
        [
          {
            animal: 'hamster',
            name: 'gerry',
            date: 2018-12-31T23:00:00.000Z,
            status: 0
          }
        ]
      ]
    ]
  ],
  [
    't-rex',
    [
      [
        0,
        [
          {
            animal: 't-rex',
            name: 'dino',
            date: 2019-12-31T23:00:00.000Z,
            status: 0
          },
          {
            animal: 't-rex',
            name: 'sauro',
            date: 2018-12-31T23:00:00.000Z,
            status: 0
          }
        ]
      ]
    ]
  ],
  [
    'sheep',
    [
      [
        0,
        [
          {
            animal: 'sheep',
            name: 's',
            date: 2018-12-31T23:00:00.000Z,
            status: 0
          }
        ]
      ],
      [
        -1,
        [
          {
            animal: 'sheep',
            name: 'sss',
            date: 2018-12-31T23:00:00.000Z,
            status: -1
          }
        ]
      ]
    ]
  ]
]
*/

分组正常,但数据不是我需要的格式。

您可以在 d3.groups 之后链接一个 .reduce,以便将嵌套数组重新转换为嵌套对象。

您可以使用 {} 初始化 reduce,因此它 returns 是一个对象。 curr[0]d3.groups 返回的每个数组将是 animal。对于从 d3.groups 返回的每个数组,curr[1] 将是 status 的数组和按 animal/ status 逻辑分组的原始项目数组。

见下文:

const data = [ 
  {animal: 'cat', name: 'mu', date: new Date(2020, 0, 1), status: -1},
  {animal: 'cat', name: 'muji', date: new Date(2021, 0, 1), status: 0},
  {animal: 'cat', name: 'mine', date: new Date(2021, 0, 1), status: 1},
  {animal: 'dog', name: 'fido', date: new Date(2021, 0, 1), status: 1}, 
  {animal: 'dog', name: 'fido2', date: new Date(2020, 0, 1), status: 1}, 
  {animal: 'dog', name: 'fido3', date: new Date(2021, 0, 1), status: 0}, 
  {animal: 'hamster', name: 'gerry', date: new Date(2019, 0, 1), status: 0}, 
  {animal: 't-rex', name: 'dino', date: new Date(2020, 0, 1), status: 0},
  {animal: 't-rex', name: 'sauro', date: new Date(2019, 0, 1), status: 0},
  {animal: 'sheep', name: 's', date: new Date(2019, 0, 1), status: 0}, 
  {animal: 'sheep', name: 'sss', date: new Date(2019, 0, 1), status: -1}, 
];

const grouped = d3.groups(
  data,
  d => d.animal,
  d => d.status
).reduce((acc, curr) => {
  let obj = {};
  curr[1].forEach(item => obj[item[0]] = item[1]);
  acc[curr[0]] = obj;
  return acc;
}, {});

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js"></script>