3

I found this piece of code and I am wondering how to display them in the following fashion in a table:

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

Code:

  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
2
  • is your wanted style a table? Commented Mar 7, 2020 at 21:31
  • how to display it in a table fashion as shown in my post above Commented Mar 7, 2020 at 21:43

1 Answer 1

1

It is just about counting the maximum chars of each column

//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)

Sign up to request clarification or add additional context in comments.

4 Comments

sorry, but that I can achieve. I need to separate them by headers, see my post above
it is throwing the error: flatMap is not a function.
I run the sample successfully, which browser and version are you using? If your browser is too old (which is odd because flatMap is quite old too) we may have to rely on lodash flatMap or so. Are you sure you want to include a library for that @BurreIfort ?
I am using chrome and is the latest version. I can run your code by clicking on "Run code snippet" just fine. but when I put it in a js file and run it, it throws the error. Let me try it and get back to you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.