Home > OS >  add objects if missing (javascript)
add objects if missing (javascript)

Time:03-03

Suppose in an array if a customer has 3 places then all the other customers need to have 3 places if any customer is missing a place then I need to add a object with customerName ,Ratings as 0,Bad ratings as 0 and Place which was missing. Please refer to the current JSON and Expected JSON for reference.

I need it this way because I'm feeding this data to chart.js as there are missing values for customers my chart is not getting plotted correctly.

Current JSON:

[
  {
    "Bad ratings": 10,
    "Ratings": 8,
    "place": "Mars",
    "customerName": "david"
  },
  {
    "Bad ratings": 50,
    "Ratings": 23,
    "place": "earth",
    "customerName": "david"
  },
  {
    "Bad ratings": 56,
    "Ratings": 34,
    "place": "earth",
    "customerName": "Kevin"
  },
  {
    "Bad ratings": 10,
    "Ratings": 8,
    "place": "Moon",
    "customerName": "Kevin"
  },
  {
    "Bad ratings": 9,
    "Ratings": 6,
    "place": "Mars",
    "customerName": "Kevin"
  },
  {
    "Bad ratings": 10,
    "Ratings": 8,
    "place": "Moon",
    "customerName": "Jessica"
  }
]

Expected JSON:

[
  {
    "Bad ratings": 10,
    "Ratings": 8,
    "place": "Mars",
    "customerName": "david"
  },
  {
    "Bad ratings": 50,
    "Ratings": 23,
    "place": "earth",
    "customerName": "david"
  },
  {
    "Bad ratings": 0,
    "Ratings": 0,
    "place": "Moon",
    "customerName": "David"
  },
  {
    "Bad ratings": 56,
    "Ratings": 34,
    "place": "earth",
    "customerName": "Kevin"
  },
  {
    "Bad ratings": 10,
    "Ratings": 8,
    "place": "Moon",
    "customerName": "Kevin"
  },
  {
    "Bad ratings": 9,
    "Ratings": 6,
    "place": "Mars",
    "customerName": "Kevin"
  },
  {
    "Bad ratings": 10,
    "Ratings": 8,
    "place": "Moon",
    "customerName": "Jessica"
  },
    {
    "Bad ratings": 0,
    "Ratings": 0,
    "place": "earth",
    "customerName": "Jessica"
  },
   {
    "Bad ratings": 0,
    "Ratings": 0,
    "place": "Mars",
    "customerName": "Jessica"
  }
]

Identified Distinct places:

what can be done once after I Identify Distinct Places & Distinct Customers.


           let UniquePlaces = []; 
             let UniqueCustomers = [];
             let uniqueData = body.map(e => e['place']).map((e, i, final) => final.indexOf(e) === i && i).filter(obj => body[obj]).map(e => body[e]);
let uniqueDatacustomerName = body.map(e => e['customerName']).map((e, i, final) => final.indexOf(e) === i && i).filter(obj => body[obj]).map(e => body[e]);
             uniqueData.forEach(element => { UniquePlaces.push(element.place)});
             uniqueDatacustomerName.forEach(element => { 
            UniqueCustomers.push(element.customerName)
           });

Any suggestions are much appreciated. Thanks :)

CodePudding user response:

It seems you want a cartesian product of places with names.

I would create a nested map, keyed by those two dimensions, and populate all combinations with a "zero" object.

Then iterate the input objects and place them at their corresponding slot in the above structure, thereby replacing the zero object with the real one.

let body = [{"Bad ratings": 10,"Ratings": 8,"place": "Mars","customerName": "david"},{"Bad ratings": 50,"Ratings": 23,"place": "earth","customerName": "david"},{"Bad ratings": 56,"Ratings": 34,"place": "earth","customerName": "Kevin"},{"Bad ratings": 10,"Ratings": 8,"place": "Moon","customerName": "Kevin"},{"Bad ratings": 9,"Ratings": 6,"place": "Mars","customerName": "Kevin"},{"Bad ratings": 10,"Ratings": 8,"place": "Moon","customerName": "Jessica"}];

let places = [...new Set(body.map(({place}) => place))];

let matrix = Object.fromEntries(body.map(({customerName}) => [
    customerName,
    Object.fromEntries(places.map(place => 
        [place, { "Bad ratings": 0, "Ratings": 0, place, customerName }]
    ))
]));
for (let item of body) {
    matrix[item.customerName][item.place] = item;
}
let result = Object.values(matrix).flatMap(Object.values);

console.log(result);

CodePudding user response:

Approach:

  1. Loop 1 create a map of how many rows are there for each name and what are the places already there for each name. It also stores the name of the customer who has all the places. Maintains a max variable with the maximum number of rows for a user.

  2. Loop 2, for the names which don't have all the rows, checks how many rows are missing, finds the places not there. Then inserts a row for each place.

const data = [{
    "Bad ratings": 10,
    "Ratings": 8,
    "place": "Mars",
    "customerName": "david"
  },
  {
    "Bad ratings": 50,
    "Ratings": 23,
    "place": "earth",
    "customerName": "david"
  },
  {
    "Bad ratings": 56,
    "Ratings": 34,
    "place": "earth",
    "customerName": "Kevin"
  },
  {
    "Bad ratings": 10,
    "Ratings": 8,
    "place": "Moon",
    "customerName": "Kevin"
  },
  {
    "Bad ratings": 9,
    "Ratings": 6,
    "place": "Mars",
    "customerName": "Kevin"
  },
  {
    "Bad ratings": 10,
    "Ratings": 8,
    "place": "Moon",
    "customerName": "Jessica"
  }
]

const dict = {}
const places = {};

let max = 0;
let ref;

for (let row of data) {
  let name = row.customerName;

  if (!dict[name]) dict[name] = 0;
  if (!places[name]) places[name] = [];

  dict[name]  ;
  places[name].push(row.place);

  max = Math.max(max, dict[name]);

  if (max === dict[name]) ref = name;
}

for (let name of Object.keys(dict)) {
  if (dict[name] === max)
    continue;

  let cnt = max - dict[name];
  let allplaces = places[ref];
  let placesToInsert = allplaces.filter((place) => !places[name].includes(place));

  for (let i = 0; i < cnt; i  ) {
    data.push({
      Ratings: 0,
      "Bad Ratings": 0,
      name,
      place: placesToInsert[i],
    });
  };
}

console.log(data)

  • Related