javascriptarraysjsoncyclenode.js-fs

Collect a field value into an array by ID field in an object array


I am unable to modify JSON file. Tried to use all my knowledge of loops (map,filter) and conditions(if,else) JavaScript. But nothing comes out. Please tell me how to make such a file from this file

[{
    "model": "2002R \"Protection Pack - Mirage Grey",
    "img": "2002r-protection-pack-mirage-grey.jpg"
  },
  {
    "model": "2002R \"Protection Pack - Mirage Grey",
    "img": "2002r-protection-pack-mirage-grey-2.jpg"
  },
  {
    "model": "550 \"White Black",
    "img": "BB550HA1-2.jpg"
  },
  {
    "model": "550 \"White Black",
    "img": "BB550HA1-3.jpg"
  },]

Should be like this

   [{
    "model": "2002R \"Protection Pack - Mirage Grey",
    "img": ["2002r-protection-pack-mirage-grey.jpg", "2002r-protection-pack-mirage-grey-2.jpg"]
  },
  {
    "model": "550 \"White Black",
    "img": ["BB550HA1-2.jpg","BB550HA1-3.jpg"]
  },
]

I tried this. But no correct result.

let modelsArray = [];
let prevModel = '';
let currentModel = '';
let pictureArray = [];
let counterModel = 0;

fs.readFile(path, 'utf-8', (err, data) => {
  if (err) console.log(err.message);

  try {
    const dataArr = JSON.parse(data);

    const newArr = dataArr.map((item, ind) => {
      currentModel = item.model;

      pictureArray.push(item['img']);

      if (modelsArray.length == 0) {
        modelsArray[counterModel] = { model: item.model };
        prevModel = currentModel;
      }

      if (prevModel !== item.model) {
        counterModel++;
        modelsArray[counterModel] = { model: item.model };
      }

      prevModel = currentModel;


      
    });

Please give me advice


Solution

  • Array::reduce is a good option to collect data from an array. Here we have an accumulator of the result array and a map where we can easily find already added models to add images to them:

    r.map.get(model)?.img.push(img)
    

    if a model isn't found add it to both the array and the map:

    r.map.set(model, r.arr[r.arr.length] = {model, img: [img]});
    

    const models = [{
        "model": "2002R \"Protection Pack - Mirage Grey",
        "img": "2002r-protection-pack-mirage-grey.jpg",
        "brand": "test brand"
      },
      {
        "model": "2002R \"Protection Pack - Mirage Grey",
        "img": "2002r-protection-pack-mirage-grey-2.jpg"
      },
      {
        "model": "550 \"White Black",
        "img": "BB550HA1-2.jpg"
      },
      {
        "model": "550 \"White Black",
        "img": "BB550HA1-3.jpg"
      },];
      
    const images = models.reduce((r, {model, img, ...props}) => {
      r.map.get(model)?.img.push(img) ?? 
      r.map.set(model, r.arr[r.arr.length] = {model, img: [img], ...props});
      return r;
    }, {arr: [], map: new Map}).arr;
    
    console.log(images);