Complex Data Transformation Puzzle in Xano (@nocodebackend)

Ray Deck builds a Xano endpoint that groups a flat list of date and name pairs into an object where each date maps to an array of unique names. He uses forEach to iterate through items, checks if each date exists with the get function, and prevents duplicate names within each date using hasanyelement before pushing to the array. Finally, he converts the grouped object back to an array with object.valuesFrom.
Chapters
So here's an interesting issue from the Xano community. We want to convert one shape of data, which is say a list of dates and name pairs, and turn it into a, a list of dates, then contain lists of names where it only has one name per date. Now, initial example, he doesn't actually have any repeating names in here, but that'd be something we wanna keep track of. We know that because it's using something here called a set. Set is a list that guarantees you only have one item per, per value, right? So you couldn't have, you couldn't do 1, 1, 2, 2, 3, 3. It would just be 1, 2, 3 because set is guaranteeing that it's only gonna be one at a time. So that's gonna be another consideration we need to constrain in order for this endpoint to work. So how would we go about this? We can create a little function in Xano and here we are here and we'll just walk through it for a second that does this very job. So the first thing we would do inside of the Xano endpoint for recreating his setup is we would want to create an empty object, which is group_data, which is exactly what we're doing in step 1. Then we're going to loop over the data that came in the door, just like he's got here, data foreach. He's just looping over it and then having iterator, we'll call it item, which is exactly what we will do here. input_data as item. And we will then say, all right, let's forEach. So we're going to pull out date and name from item. This is a very terse syntax we have in JavaScript. It's a little bit more verbose in Xano. We're going to create a variable called date that's based on item.date and we'll create something called name that's based on item.name. Now the next thing we want to do is we want to find out whether or not there, there already exists an item in group data that matches that particular date, right? Because since group data is an object, this can be keyed by the date and the value is going to be the, the name that's supposed to go with it. We now at, we are going to try to get from grouped_data based on the key or a path of the date that we had pulled out of the dataset. And we're going to call that record. And what will happen here with get is if it doesn't find anything that matches it, it'll return a null, right? Because that'll be the default value. You can't use dot syntax because dot syntax will throw an error. So the, so now we can ask if the record is equal to null, i.e., didn't find anything, there is no matching date. And that basically matches the, the else condition he's got here. I sort of did it in reverse. So if in, in the event that it does not already have the, have that date as a record, then we just need to instantiate it, creating a new record, which will be an object that will have the date and have a name, which will be a list with just this first name in it. So we do that. We say if it's null, then we create a value called record, which is the empty object, which we will set on a path called date, which will be the date that was passed that we extracted from group data. And the name that is going to be an empty, there'll be initially an empty array that you then just push in that one name. And that gives you one name at the end of this process. And we can just sort of prove this out for a second by going to utility functions, stop and debug, and say this is going to be a record. And if I were just to quickly run that using the same data as he had as an example, you'll see that creates Liam. So it creates an initial object with a date and a single array with a name of Liam. Great. So let's, that seems to work properly. And then the, but if it does already have something for that date, then its job is to find out if there is, if that name already exists in the array. And this is a little tricky. Because now what we have is a list instead of an object. And the way that we do that is we just use the has_any_element to find whether or not this exists in the array by saying, hey, does this name already exist in the iterator of record.name? 'Cause record.name itself is a list. And if it does find something, it's called has_name will be true. If it doesn't find anything, has_name will be false. In the event that has_name is false, which means that we're now adding a new name, only then Do we take the name, which remember is this list here, this list that includes Liam, and we add the new name. In our previous example, we would expect to go Liam and then add Liam 1 to that list. So what all this does is it creates for us a bit of an object here and then having updated record, we then make sure that grouped data just gets set so that the, the record just gets put back in its slot. Inside the group data itself. So that way we keep on making sure that group data has one record per, per date. Fantastic. And now we can basically evaluate what happens at the end of that loop by doing a utility functions and a stop and debug. And I'll say, let's look at group data and we rerun that. And now we can see we have an object that's keyed by the date, just like he's got, right? This object keyed by date. And each element has a record which has a date and has a name. Now the final thing he wants to do is make sure just do object.values, it returns as a list. And we can do that exactly the same way here by using object.valuesFrom, which is available if we want to just quickly create it, we would go to data manipulation, we go to arrays and we would, sorry, actually it's under arrays, it's under objects. So under data manipulation, under objects, we have getValues. And that's what we're using here. getValuesFromGroupData. And I just call that output. And then we, and then we just return the output. And when we do that, we get the exact same list as what he wanted to create. Now, in order to really test this, make sure it's a set, we want to see if a repeat were to hit. So Liam Maxwell, what happens if I have a second Liam also for that same date? It basically should ignore it, but only the first Liam should work. And if I do that, it doesn't like that because it's actually, uh, formatted Liam1 Liam1. But if I make this into Liam2, now I get Liam1 Liam1 Liam2. And you can see how this then shows how we can really transform data that is in a relatively complex structure into a new relatively complex structure using combination of array, object, and finally a transformation between arrays and objects and arrays. Right here in Xano.










