Home > Net >  loop array of objects and add obj for missing entries
loop array of objects and add obj for missing entries

Time:11-17

I am doing a particular task but it isnt dynamic. Below i have a eventList and a response from API. Based on the eventList, i have to rearrange the response and sort it.

For eg. below, i have eventList XM1, XM2, XM3, So i have to rearrange response, in such a way that eventTitle with XM1 becomes first element, eventTitle with XM2 is second element and XM3 is third element. And this will repeat till the last element of response is reached. In Below example, once id 1, 3, 2 are pushed sequentially object id 4 is left. But id with object 4 has eventTitle XM2. That means XM1 has to be filled with empty object and XM3 has to be filled with another empty object.

let eventList = [ "XM1", "XM2", "XM3" ];

let response = [
    { "id": 1, "eventTitle": "XM1" },
    { "id": 2, "eventTitle": "XM3" },
    { "id": 3, "eventTitle": "XM2" },
    { "id": 4, "eventTitle": "XM2" },
]

The result of this sequentially placing elements and filling the gaps with id=0 is shown below.

let sortResponse = [
    { "id": 1, "eventTitle": "XM1" },
    { "id": 2, "eventTitle": "XM2" },
    { "id": 3, "eventTitle": "XM3" },
    { "id": 0, "eventTitle": "XM1" },
    { "id": 4, "eventTitle": "XM2" },
    { "id": 0, "eventTitle": "XM3" },
]

Here is the code i use to sequentially sort elements and add empty objects in the output. But this is not dynamic. i always knew that my eventList will be 3 elements. but i want to make it dynamic so that even if my eventList is 10 elements, i should be able to sort and fill missing objects in it. Can someone please let me know how to achieve this dynamically

let sortResponse = []

if (eventList.length === 3 && response.length > 0) {
    let fil1 = response.filter(function (el) {
      return el.eventTitle === eventList[0];
    });
    let fil2 = response.filter(function (el) {
      return el.eventTitle === eventList[1];
    });
    let fil3 = response.filter(function (el) {
      return el.eventTitle === eventList[2];
    });

    let obj = { id: 0, eventTitle: "" };
    let obj1 = { id: 0, eventTitle: "" };

    //check if fil1 has most elements and use it to iterate through each fil1 and push fil2 and fil3
    if (fil1.length >= fil2.length && fil1.length >= fil3.length) {
      for (let j = 0; j < fil1.length; j  ) {
        sortResponse.push(fil1[j]);
        if (!fil2[j]) {
          obj.eventTitle = eventList[1];
        }
        sortResponse.push(fil2[j] ? fil2[j] : obj);
        if (!fil3[j]) {
          obj1.eventTitle = eventList[2];
        }
        sortResponse.push(fil3[j] ? fil3[j] : obj1);
      }
    }
    //check if fil2 has most elements and use it to iterate through each fil2 and push fil1 and fil3
    else if (fil2.length >= fil1.length && fil2.length >= fil3.length) {
      for (let j = 0; j < fil2.length; j  ) {
        if (!fil1[j]) {
          obj.eventTitle = eventList[0];
        }
        sortResponse.push(fil1[j] ? fil1[j] : obj);
        sortResponse.push(fil2[j]);
        if (!fil3[j]) {
          obj1.eventTitle = eventList[2];
        }
        sortResponse.push(fil3[j] ? fil3[j] : obj1);
      }
    }
    //check if fil3 has most elements and use it to iterate through each fil3 and push fil1 and fil2
    else if (fil3.length >= fil1.length && fil3.length >= fil2.length) {
      for (let j = 0; j < fil3.length; j  ) {
        if (!fil1[j]) {
          obj.eventTitle = eventList[0];
        }
        sortResponse.push(fil1[j] ? fil1[j] : obj);
        if (!fil2[j]) {
          obj1.eventTitle = eventList[1];
        }
        sortResponse.push(fil2[j] ? fil2[j] : obj1);
        sortResponse.push(fil3[j]);
      }
    }
}

CodePudding user response:

This isn't particularly optimized since we're "finding" the next element over and over again in our loop, but it's pretty dynamic so it might work for you.

WARNING: This also will NOT terminate if your initial response object contains an event with an event title that is not in the eventList array. In that case, the loop will execute indefinitely and will just keep adding "filler" events to the new response array.

let eventList = [ "XM1", "XM2", "XM3" ];

let response = [
    { "id": 1, "eventTitle": "XM1" },
    { "id": 2, "eventTitle": "XM3" },
    { "id": 3, "eventTitle": "XM2" },
    { "id": 4, "eventTitle": "XM2" },
]

let newResponse = [];
let i = 0;
while(true) {
  // Get the event title we are looking for. We'll have to manage looping through event titles kind of manually.
  let currentEventTitle = eventList[i];
  // Grab the index of the NEXT event that matches the current event title.
  let nextEventIndex = response.findIndex( event => event.eventTitle === currentEventTitle );
  // If our response has an event that matches, return that event from the current response array, otherwise we'll construct a "filler" event
  let nextEvent = nextEventIndex !== -1 ? response.splice(nextEventIndex, 1)[0] : { "id": 0, "eventTitle": currentEventTitle };
  // Push the found or constructed event to a new array.
  newResponse.push(nextEvent);
  // Now we'll need to manage our eventlist looping and exit condition.
  // First increment our eventList index or start again from 0 if we've reached the end.
  i  ;
  if(i === eventList.length) i = 0;
  // Our exit condition is 1) if our starting response array is empty and 2) if we've gotten to the end of our event list
  // which at this point means we've looped back around and our index is 0 again.
  if(response.length === 0 && i === 0) break;
}

document.getElementById("result").innerText = JSON.stringify(newResponse, null, 4);
<pre id="result"></pre>

  • Related