Make a Nested Array From a Flat Array in @nocodebackend

Ray Deck shows how to transform a flat array into nested groups using Xano no-code functions. He extracts unique act identifiers, then uses a reducer with findallelements to collect scenes by act and wrap them in objects. The method works regardless of item order and can include optional sorting.
Chapters
Okay, so let's say you want to nest an array, like you got a big old array like this one here where we have, you know, a bunch of things that are sort of at two different levels of capture, right? Like, you know, I might have, you know, act and scene, right? Like from a play, right? So I can have, you know, maybe I have two scenes in act one and I have, I'm going to have, you know, one scene in act 2, and then I'm going to have like another, you know, you know, another one down here, which is just going to be in act 3, you know, I'll also have a scene, right? And you know, what I'm trying to do is I want to cluster them, right? So that all the scenes from a given act are together. But right now what I've got is sort of just a big old flat array. So what I'm going to do is I want to group it by act., right? And I want the, you want Ray, which is gonna give me basically a list of acts. And then for each act, you'll tell me what the scenes are that go along with it. And if I have a little bit of extra data, I don't care quite as much. What I really care about is just being able to associate the scenes with the proper acts. So let's start with that and ask what we can do with that. So the first thing we can do is find out what our list of acts are. And that can be a, you know, that, that can seem like it's a little bit of a tricky thing, but there's actually a one-liner we can do in this, which is we create a new variable, we'll call it keys, which is gonna be based on that array just like we have here. And then we're gonna run a GET because whenever you run a GET on an array of objects and you pass it a single path, it creates an array of the values at that particular path, right? So what'll happen here is if I ask for the input key using this GET, it'll pull the 1 and the 1 and the 2 and the 3. In fact, let me just illustrate that right now. I'm going to throw in a little stop and debug, always my favorite function here. And I'm going to say, do, do, do, do, tell me about keys, right? Okay, so let's run this for a second. And it's keys 1, 1, 2, 3. Now of course these are duplicated, right? I'm just looking for a list of unique keys. And for that we actually have another filter. It's called unsurprisingly unique, which gets the actual unique values. It has some more complexity in terms of its interface where you can set a path for when you're dealing with, you know, comparing, finding uniqueness in a list of objects. But if you're just looking at like a list of numbers or a list of strings like we are right now, don't need to set that at all. You just use unique filter and the effect of it will be, if I run it again, hey look, I just get the 1, 2, and 3, right? All my duplicates get taken away. So let's get rid of that. Great. So now I've got my list of keys. What I want to do is loop over all of these acts and find out where the scenes are because it's actually no guarantee in terms of how this thing works. Ooh, I didn't mean to lose that. Great. So here we are with my list again. I had accidentally booped it for a second. And what I want to do now is loop over those keys we just talked about, the 1, the 2, and the 3. To go find out what scenes actually go with them. So to do that, we're going, this is essentially a reducer because we're going to produce a result that is going to be the different shape and a different number of keys than what we started with. So sometimes we talk about mapping, which is we go over each element in an array. This is going to be a reducer where we're going to produce something that is differently shaped than where we start. And to do that, we create a variable which we call an accumulator, but I'm just calling it output right now, which is just gonna be a blank array. And this is gonna be my array of actually acts that I'm going to collect in here. And then for each act, right? So I'm looping over my keys, my keys are my acts. I'm going to just find out which of these elements are associated with my particular act. And I can do this again in a one-liner in Xano using the find_all_elements. And you know, I could ask about the initial array and ask for which ones the, key, right, which is at whatever path I specify key to be, is going to be, it is equal to whatever this item is. And so for each element. So, you know, first I'm gonna be looking at act 1, I'm saying, okay, I'm starting with act equals 1 and this passes, this passes, this fails, this fails, right? And so this will produce for me this list of arrays, which is pretty handy to have. Now I've got my scene A and my scene B. And then I can put them and I'm now collecting them into a list of what I'm just calling elements for lack of a better term. And then I'm creating a sort of a wrapping object for it. That way I know what the key is going to be. That way I can just so say I'm gonna have a top-level object that has an active one and then it's going to have a member called elements. And of course you probably wanna change that name for whatever your business logic's going to be. But that's basically gonna be each of the scenes that I have in here. Okay, and then having created that, I now have basically for every, for Act 1, I have an object that contains both identifying it as Act 1 and then all the scenes it goes with. And I'm going to use array at end to put this at the end of my output array. So far so good, pretty easy. Ding, ding, ding. And then, and should loop through that for each of these acts and each of these scenes. So we can, and then at the end we're just gonna return output 'cause that's what we're doing as a function here. So let's see how this works. Okay, so I have an array here, right? 3 elements in the array, 1 for each of the X, X1, X2, X3. And then I have seen 1B, 2A, and 3A. Okay, so far that seems pretty encouraging. So what if we say we want to insert another act 2 scene B underneath all this, what if it comes in out of order? Does it still work? Well, let's see here. We'll compress that and we'll say, okay, act 1, 1, act 2, A, B, look, it collects act 2 together even though they weren't actually in the array together. And I think I can do something similar by putting an act 3 thing at the beginning. So I will say this is gonna be act 3. And by the way, there's no particular reason that the acts have to be strings, they could be anything. And then I will say scene and we'll say Z. Okay, cool. Let's try running that. Okay, now the cool thing is actually picked up act 3 first. So one of the things you'll find about the array that's getting generated is it will, it is a little bit here at the mercy of in what order it finds the keys. Now, sort of a thing we can do here is we can actually add another filter here and we can just say we want to sort the array and then, yeah, so if we did this and I reran this, you see once again it gives me Act 1 first because I just made sure that I sorted the keys. So it goes 1, 2, 3 instead of how in the order in which you found them. And you know, throwing in these uniques and sorts and making use also of the looping around to create the reducer function, the finding all elements. These are all things that allow you to do very complex manipulation in Zano relatively tersely, which is great because often we wind up wanting to do more complicated things as we are dealing with data and want to deliver it back to the front end the way that the front end doesn't have to do as much work or as much thinking in order to get what it needs. This is the kind of hardest 5% work that we do all the time here on SageChange. And I hope that you found it helpful.










