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>