deno_std icon indicating copy to clipboard operation
deno_std copied to clipboard

`transposeRecords` for collections API

Open scarf005 opened this issue 2 years ago • 1 comments

Is your feature request related to a problem? Please describe.

While i was creating a table JSX component, I found it convenient to pass in array of title and content then to pass array of title and content. I could make a PR, however I'm not certain whether it'll have lots of use cases.

type TablePair = { title: VNode; content: VNode }

const toTable = (elems: TablePair[]) => {
  const { content, title } = transposeRecords(elems)
  return (
    <table>
      <tr>{content}</tr>
      <tr>{title}</tr>
    </table>
  )
}

Describe the solution you'd like

playground link

export function transposeRecords<K extends string, T>(
  records: Record<K, T>[],
): Record<K, T[]> {
  const result = {} as Record<string, T[]>
  for (const record of records) {
    for (const [key, value] of Object.entries(record)) {
      // deno-lint-ignore no-extra-semi
      ;(result[key] ??= []).push(value as T)
    }
  }
  return result
}

const transposed = transposeRecords([
  { a: "foo", b: 1, c: true },
  { a: "bar", b: 2, c: false },
  { a: "baz", b: 3, c: true },
])
// const transposed: Record<"a" | "b" | "c", (string | number | boolean)[]>

assertEquals(transposed, {
  a: ["foo", "bar", "baz"],
  b: [1, 2, 3],
  c: [true, false, true],
})

Describe alternatives you've considered

https://stackoverflow.com/questions/53380761/how-to-transpose-objects-in-typescript

scarf005 avatar Jun 04 '23 08:06 scarf005

I'm a fan. Care to make a PR?

lino-levan avatar Aug 16 '23 02:08 lino-levan