Отобразить сгруппированные элементы в JavaScript - PullRequest
3 голосов
/ 08 марта 2020

Я нашел этот фрагмент кода, и мне интересно, как отобразить их в таблице следующим образом:

    Males | Name   | occupation
    ---------------------------
          | Jeff   | x
          | Taylor | x
   Females| Name   | occupation
   -----------------------------
          | Megan  | x
          | Madison| x

Код:

  function groupArrayOfObjects(list, key) {
      return list.reduce(function(rv, x) {
        (rv[x[key]] = rv[x[key]] || []).push(x);
        return rv;
      }, {});
    };

    var people = [
        {sex:"Male", name:"Jeff"},
        {sex:"Female", name:"Megan"},
        {sex:"Male", name:"Taylor"},
        {sex:"Female", name:"Madison"}
    ];
    var groupedPeople=groupArrayOfObjects(people,"sex");
    console.log(groupedPeople.Male);//will be the Males 
    console.log(groupedPeople.Female);//will be the Females

1 Ответ

1 голос
/ 08 марта 2020

Это просто подсчет максимального числа символов в каждом столбце

//copy pasted
function groupArrayOfObjects(list, key) {
  return list.reduce(function(rv, x) {
    (rv[x[key]] = rv[x[key]] || []).push(x);
    return rv;
  }, {});
};
var people = [
    {sex:"Male", name:"Jeff"},
    {sex:"Female", name:"Megan"},
    {sex:"Male", name:"Taylor"},
    {sex:"Female", name:"Madison"}
];
var groupedPeople=groupArrayOfObjects(people, "sex");
//--------
const headers = { name: 'name', occupation: 'occupation' }

const out = Object.keys(groupedPeople).flatMap(k => groupedPeople[k].flatMap((p, i) => {
  p.occupation = p.occupation || 'x'
  const sex = p.sex
  p.sex = ''
  return i === 0 ? [{ sex, ...headers }, p] : p
}))

function dump (arr) {
  // count each column maximum char
  const counts = arr.reduce((counts, p) => {
    Object.keys(p).forEach(f => (counts[f] = Math.max(counts[f], p[f].length)))
    return counts
  }, Object.keys(arr[0]).reduce((o, f) => (o[f] = 0, o), {}))
  const cv = Object.values(counts)
  const s = cv.reduce((acc, c) => acc + c, 0)
  const tot = s + (cv.length) * 2 - 1 + (cv.length - 1) //fields, pad, separator
  const hr = '-'.repeat(tot)
  console.log(
    arr.flatMap(p => {
      const row = Object.keys(p).map(f => {
        // pad the field to its maximum char
        return ` ${p[f]}`.padEnd(counts[f] + 2, ' ')
      }).join('|')
      if (p.sex.length) {
        return [row, hr]
      }
      return row
    }).join('\n')
  )
}
dump(out)
...