Home > Software engineering >  Inserting a 0 at a specific index if an object does not contain a certain value
Inserting a 0 at a specific index if an object does not contain a certain value

Time:08-19

I am trying to populate a google chart. I have two values I am creating

  1. is an array of names that are contained in the value
  2. is an array of values contained in the data

I need to insert a 0 at the index where the value would be if it were present in the data to keep the data inline for the graph.

My data:

const MOCK = {
        data: [
          {date: "Aug.03", name: "name1", visits: 3 },
          {date: "Aug.03", name: "name2", visits: 3 },
          {date: "Aug.04", name: "name1", visits: 2 },
          {date: "Aug.05", name: "name1", visits: 3 },
          {date: "Aug.05", name: "name2", visits: 3 },
          {date: "Aug.05", name: "name3", visits: 3 },
          {date: "Aug.06", name: "name1.", visits: 7 },
          {date: "Aug.06", name: "name3", visits: 8 },
          {date: "Aug.07", name: "name2", visits: 1 },
          {date: "Aug.07", name: "name3", visits: 13 },
          {date: "Aug.08", name: "name2", visits: 12 },
          {date: "Aug.08", name: "name3", visits: 15 },
          ]
      }

Name array:

// create an array with each name
      const nameGroups = MOCK.data.map((item) => item.name);
// remove duplicates from nameGroups
      const cleanNameGroups = [...new Set(nameGroups)];
// add empty string for axis label
      const finalNames = ["", ...cleanNameGroups]

console.log(finalNames)
// ["", "name1", "name2", "name3"]

Second Array Group:

const dateGroups = Object.entries(MOCK.data.reduce((acc, { date, ...item }) => ({
        ...acc,
        [date]: [...(acc[date] || []), item],
      }), {})).map(([key, value]) =>  [key, ...Object.values(value.map(value => value.visits))]);


console.log(dateGroups)
[["Aug.03", 3,3],["Aug.04",2],["Aug.05", 3, 3 ]]

So I need to insert a 0 where the values are missing for their corresponding name so that each array in dateGroups is the same length

I am trying to get dateGroups to look like:

[["Aug.03", 3,3,0],["Aug.04",2,0,0],["Aug.05",0, 3, 3 ]...]

CodePudding user response:

You can do this by reducing the array to a dictionary of {date: {names:visits}}, then we can loop over the properties in that dictionary to to create the output you're looking for.

  1. Use the set of names finalNames to create a base default object newObj that'll be set for each date in the dictionary.

    • We first map the name array to [name, 0], i.e. [[name1, 0], [name2, 0]]
    • Then we create an object from that array using Object.fromEntries. I logged that object to the console in the code.
  2. Reduce the data array into a dictionary/object.

    • Check if the dictionary has an property for the current row's date:
      • If not, set it to newObj that we just made.
    • Add the visit amount to the appropriate name in the object
  3. Use for in to loop through the dates in the dictionary, and use Object.values to convert {name1: 1, name2: 0, name3: 3} to [1,0,3] and push it with the property name, which is our date, into the an output array.

const MOCK = {
        data: [
          {date: "Aug.03", name: "name1", visits: 3 },
          {date: "Aug.03", name: "name2", visits: 3 },
          {date: "Aug.04", name: "name1", visits: 2 },
          {date: "Aug.05", name: "name1", visits: 3 },
          {date: "Aug.05", name: "name2", visits: 3 },
          {date: "Aug.05", name: "name3", visits: 3 },
          {date: "Aug.06", name: "name1", visits: 7 },
          {date: "Aug.06", name: "name3", visits: 8 },
          {date: "Aug.07", name: "name2", visits: 1 },
          {date: "Aug.07", name: "name3", visits: 13 },
          {date: "Aug.08", name: "name2", visits: 12 },
          {date: "Aug.08", name: "name3", visits: 15 },
          ]
}

const nameGroups = MOCK.data.map((item) => item.name);
const cleanNameGroups = [...new Set(nameGroups)];
const finalNames = [ ...cleanNameGroups]

const newObj = Object.fromEntries(finalNames.map(name => [name,0])) // Defualt object for each date. Initializes all visit quantities to 0.
console.log('New Object: ', newObj)

const dateDict = MOCK.data.reduce((acc, obj) => {
  if (!acc[obj.date]) {
    acc[obj.date] = {...newObj}
  }
  acc[obj.date][obj.name]  = obj.visits;
  return acc
},{})
console.log('Date Dictionary: ', dateDict);

let output = []
for (let date in dateDict) {
  let visitArray = Object.values(dateDict[date])
  output.push([date, ...visitArray])
}

console.log('Output: ', output)

  • Related