1

In the following stackblitz sample. I have the following data:

My table is displaying what I want, As you can see inside the timeline object the "start" values are exactly the same as the ones inside the aval array

Therefore, is there anyway I can display those table headers without the timeline object? (using filter, reduce or Array.from) Maybe I can loop to that very nested aval array and get them as an individual array kinda like

"aval" = ["11-19", "11-20", "11-21", "11-22"]

I'm using filter but getting nowhere so far.

DATA:

{
  "timeline": {
    "timeline_values": [{
        "tag": 0,
        "start": "11-19"
      },
      {
        "tag": 1,
        "start": "11-20"
      },
      {
        "tag": 2,
        "start": "11-21"
      },
      {
        "tag": 3,
        "start": "11-22"
      }
    ]
  },
  "employees": [{
      "EmployeeID": "56250f",
      "FirstName": "Downs",
      "aval": [{
          "start": "11-19",
          "end": "2",
          "ava": "30",
          "health": "4"
        },
        {
          "start": "11-20",
          "end": "2",
          "ava": "40",
          "health": "4"
        },
        {
          "start": "11-21",
          "end": "2",
          "ava": "50",
          "health": "4"
        },
        {
          "start": "11-22",
          "end": "2",
          "ava": "60",
          "health": "4"
        }
      ]
    },
brohymn
  • 460
  • 5
  • 22
  • Can you upload the full data and format it? – codejockie Nov 23 '18 at 00:03
  • Is your question how to create an array called `headers` like `["11-19", "11-20", "11-21", "11-22"]` from the `employees.aval` array in the data you posted? – slider Nov 23 '18 at 00:08
  • data is inside the grid.component.ts the variable is called **this.localObject** , please open the stackblitz – brohymn Nov 23 '18 at 00:10

2 Answers2

2

Assuming you wanted the aval list from employee list, you can try a combination of map and reduce

  • Map to create arrays of array which will have all start aval values for a particular employee employee -> aval -> start

  • Reduce to flatten the array of arrays

  • Finally use ES6 Set to pick unique values.

const employees = [{
    "EmployeeID": "56250f",
    "FirstName": "Downs",
    "aval": [{
        "start": "11-19",
        "end": "2",
        "ava": "30",
        "health": "4"
      },
      {
        "start": "11-20",
        "end": "2",
        "ava": "40",
        "health": "4"
      },
      {
        "start": "11-21",
        "end": "2",
        "ava": "50",
        "health": "4"
      },
      {
        "start": "11-22",
        "end": "2",
        "ava": "60",
        "health": "4"
      }
    ]
  },
  {
    "EmployeeID": "56250f",
    "FirstName": "Mckenzie",
    "aval": [{
        "start": "11-19",
        "end": "2",
        "ava": "1",
        "health": "4"
      },
      {
        "start": "11-20",
        "end": "2",
        "ava": "2",
        "health": "4"
      },
      {
        "start": "11-21",
        "end": "2",
        "ava": "3",
        "health": "4"
      },
      {
        "start": "11-22",
        "end": "2",
        "ava": "4",
        "health": "4"
      }
    ]
  }, {
    "EmployeeID": "56250f",
    "FirstName": "Charles",
    "aval": [{
        "start": "11-19",
        "end": "2",
        "ava": "100",
        "health": "4"
      },
      {
        "start": "11-20",
        "end": "2",
        "ava": "200",
        "health": "4"
      },
      {
        "start": "11-21",
        "end": "2",
        "ava": "300",
        "health": "4"
      },
      {
        "start": "11-22",
        "end": "2",
        "ava": "400",
        "health": "4"
      }
    ]
  }
]

const mappedAvals = employees.map(emp => emp.aval.map(av => av.start));
console.log("************* MAPPED AVALS **************");
console.log(mappedAvals);
console.log("************* MAPPED AVALS **************");

const flattenedAvals = mappedAvals.reduce((acc, aval) => [...acc, ...aval], []);

console.log("************* FLATTENED AVALS **************");
console.log(flattenedAvals);
console.log("************* FLATTENED AVALS **************");

const distinctAvals = [...(new Set(flattenedAvals))];

console.log("************* DISTINCT AVALS **************");
console.log(distinctAvals);
console.log("************* DISTINCT AVALS **************");
Nandu Kalidindi
  • 6,075
  • 1
  • 23
  • 36
  • Thanks. Reduce is not my forte. may I ask a good source of learning ? – brohymn Nov 23 '18 at 00:23
  • Trying out multiple examples like adding a list of numbers, counting the occurrences of characters, merging lists etc will definitely get you started but sorry, I am not aware of any particular good sources. The way you use the accumulator argument is the key to reduce method IMHO. – Nandu Kalidindi Nov 23 '18 at 00:27
0

You can also use flatMap (if it's supported) and a Set:

const aval = [...new Set(employees.flatMap(e => e.aval.map(a => a.start)))];

const employees = [{
    "EmployeeID": "56250f",
    "FirstName": "Downs",
    "aval": [{
        "start": "11-19",
        "end": "2",
        "ava": "30",
        "health": "4"
      },
      {
        "start": "11-20",
        "end": "2",
        "ava": "40",
        "health": "4"
      },
      {
        "start": "11-21",
        "end": "2",
        "ava": "50",
        "health": "4"
      },
      {
        "start": "11-22",
        "end": "2",
        "ava": "60",
        "health": "4"
      }
    ]
  },
  {
    "EmployeeID": "56250f",
    "FirstName": "Mckenzie",
    "aval": [{
        "start": "11-19",
        "end": "2",
        "ava": "1",
        "health": "4"
      },
      {
        "start": "11-20",
        "end": "2",
        "ava": "2",
        "health": "4"
      },
      {
        "start": "11-21",
        "end": "2",
        "ava": "3",
        "health": "4"
      },
      {
        "start": "11-22",
        "end": "2",
        "ava": "4",
        "health": "4"
      }
    ]
  }, {
    "EmployeeID": "56250f",
    "FirstName": "Charles",
    "aval": [{
        "start": "11-19",
        "end": "2",
        "ava": "100",
        "health": "4"
      },
      {
        "start": "11-20",
        "end": "2",
        "ava": "200",
        "health": "4"
      },
      {
        "start": "11-21",
        "end": "2",
        "ava": "300",
        "health": "4"
      },
      {
        "start": "11-22",
        "end": "2",
        "ava": "400",
        "health": "4"
      }
    ]
  }
]

const aval = [...new Set(employees.flatMap(e => e.aval.map(a => a.start)))];
console.log(aval);
slider
  • 12,810
  • 1
  • 26
  • 42
  • 1
    This solution is much cleaner and it works , however there is a couple of things to consider. First, in Angular/ typescript, I have to change the data type of employees from any[] to any, which sometimes cannot be ideal. Also according to mdn IE and EDGE don't support it. they provide an alternative with reduce and concat tho. – brohymn Nov 23 '18 at 15:41
  • @brohymn as for your second point about IE and Edge, the Typescript you write in your angular app is transpiled to Javascript that should work in all browsers: https://angular.io/guide/typescript-configuration – slider Nov 23 '18 at 15:53