List Shifter: Reverse, Rotate, Swap and ITERATE (Loop) Over Bubble Lists | Now Part of Floppy

Hey @dhlewis (also, @themoatapp, what I say here will also be helpful to you):

So List Shifter, much like a custom state, is just a place to hold some list. And then, it gives you some utility functions to modify that list (e.g., reverse it, sort it, etc.) and outputs that modified list in a new location (List Shifter’s Shifted List output).

It also can be used to create entirely new lists and send them to the Processed List and/or Custom List outputs.

One thing that’s maybe spinning you is that Bubble doesn’t allow us to create arbitrary objects in the page. The only objects that Bubble has are Things (custom data types you create and are stored in the database) and (to a lesser extent) the results of API calls (which sort of look like Things, but do not have unique IDs.

So, you’re thinking about your API call results as being a list of objects with three fields (username, a, and b). And then you want to construct some new object with 5 fields (username, a, b, a*b, and a*b*some_constant_c)

Note that you can’t, in Bubble, create such an object. But you can create lists of individual data types (a list of strings/texts, a list of numbers, etc.).

So you can construct what I call parallel lists. That is, a set of lists where all the nth entry in one list corresponds to the nth entry in some other list.

So in your case you have the results of an API call with three fields that you can either store in a custom state or (perhaps) a List Shifter (see the aside below).

Aside: I don’t have an easy way to test this, but I’m not certain that List Shifter properly supports the raw response from an API get. (I realized recently that most of my plugins that deal with lists make an assumption about Things that causes them to be a little confused by lists that are API responses.) List Shifter is a little bit different because, instead of explicitly turning a Thing into its unique ID, it actually just spits the object itself out to the outputs. This isn’t documented behavior – the plugin docs suggest that Things be converted to their unique IDs – but it works and I think the same goes for API responses, but FYI, that you might have to store the results of an in-page API call to a custom state if you find that List Shifter doesn’t do it right.

Anyway, having your API response (stored in a custom state or in a List Shifter - let’s call it LS API), you can have additional List Shifters that hold the decomposed values. That is, a List Shifter of type text to hold usernames (set its source to be something like LS API's Original List's each items username) . And similarly you can have List Shifters of type number (let’s call them List Shifter A and List Shifter B) for a and b – set their sources like LS API's Original List's each item's a / LS API's Original List's each item's b.

And then to compute your a*b, you would use the PROCESS List action. You can trigger that action when List Shifter B is initialized/updated. You’d set that up like this:

What this says is, "for each item in List Shifter B, multiply it by the corresponding Item in “LS Type List Constant”. And we push each computed value on to the Processed List by setting this option:

LS Type List Constant is provided by a field in the PROCESS List dialog, which appears way down at the bottom. (“LS Type List” means, “a list of the same type as this List Shifter”).

You’d set that up as being List Shifter A’s Original List, like so:

And so when this runs, List Shifter B’s Processed List now contains the results of a*b.

We could further set up another List Shifter to compute each item a*b times some constant c. The smart way to do this is to create a List Shifter C which takes List B’s Processed List as its list source (“List to Shift”), and imports the constant C via the Use Scalar input:

Such a List Shifter will Initialize/Update whenever either value changes. So we can set up a PROCESS List action on List Shifter C that fires whenever it updates, like so:

And when this runs, List Shifter C’s Processed List will contain the values of a*b*c. (And it will automagically recompute should the list of a*b or constant c change.

And now you can visualize your results either as text or in a Repeating Group, as shown in the demo below.

Here’s a simple example, where instead of lists “a” and “b” coming from a API call, they are just lists of numbers generated by List Shifter itself:

Run mode: https://list-shifter-demo.bubbleapps.io/version-test/listwise_multiply?debug_mode=true

Edit mode: List-shifter-demo | Bubble Editor

1 Like

I see in the Selected State Video that the selected region turns green. Was this a second condition that was setup? Can you show me what this looks like or give some guidance? I have this setup but it doesn’t highlight the item. Thanks for the amazing plugin! Looking forward to at least buying you a coffee :grinning:

@chasebwells, yeah, there’s just a group that spans the repeating group cell behind everything else in the RG cell. The data source for the group is of type number and the source is Current cell's index.

And then there’s a condition on it like: When This Group's number is List Shifter's Selected Item Number... change the background style and color.

1 Like

I would like to change an icon to another “Checked” icon. Do you know how I would go about doing that instead of the group?

You won’t be surprised at my answer: Yes. Yes I do. Just do that.

Hey Keith,
Thanks SO MUCH for the really clear and detailed response.
I will be giving this a try later today and will let you know how it goes.
I just sent some karma your way :wink:
Yours,
Dennis

I get it…On another note I can’t extract the value of Selected Item Number into a text field or use it at all although it shows it in the debugger…No need to reply, just a newbie.

Hi @keith,

Thanks for your elaborate response. I am still a little confused and was wondering if you could help me out from here. Perhaps it is because the two “lists” I am trying to multiply are not the same length and I am not trying to multiply item#n from list A and item #n from list b.

I figured out how to achieve this using the iterate function. If I showed you how I did it with Iterate it might make more sense. There is one major caveat: The output list will contain duplicate values and custom states omit duplicate values making it a no go to what would otherwise be the solution.

I am unsure how I would set up the same operation/logic using Process. I am sharing a short video and the editor to show you how it is set up with iterate. Might you take a look at it? I would really appreciate it if you could show me how to do this with process instead.

Video: Project Name - VEED

Editor: Moat10-11-28 | Bubble Editor

Hi @keith,

I’m digging into ListShifter’s PROCESS system. I am using the ListShifter element to grab a bunch of a stock price information (OPEN, HIGH, LOW, CLOSE). That all works fine.

I want to use the ListShifter PROCESS system to basically take that list and do math against two of those items (HIGH-LOW). But when I’m trying to set it up, The Operand X and Operand Y variables do not let me select the “high” or “low” portions of the data,

Is it possible to do this? I can see where I can set ListShifter A to contain only all the Open prices and then I can do basic math on that list, but I want to do basic math on High and the Low. I cannot select Operand X as ListShifter A, and then do a math function using ListShifter B as Operand Y.

Any guidance or advice?

Hey @chasebwells, Selected Item Number will be empty unless you’ve explicitly set it with the SET Selected action. Once set, it’s a number. If you “clear” the selected item number (by leaving the “Item Number” field empty), the value goes to 0 (indicating no selection - the documentation is slightly wrong there - it implies that the value becomes empty, but it actually becomes 0).

I assume what you’re putting into List Shifter is either a Thing or the result of an API call? (If so, which is it?)

So now you have a list of those objects in a List Shifter. And those objects have fields on them for open, high, low, and close price, right?

If they are Things (and possibly if they are API responses - I’ve not testing that) you could use the SET Process FIELD of Interest action before the PROCESS List to actually retrieve the values of up to 3 fields. The values of those fields then become available as “List Item’s Field of Interest 1”, “List Item’s Field of Interest 2”, etc. in the operand pulldowns.

But this is conceptually a bit difficult and you potentially have 4 fields that you want to work with, so this might not really be helpful to you.

A (possibly better) approach is to just use multiple List Shifters. So your first one is your list of Stock Price objects (or whatever they are called) - let’s call it LS Stock Prices. Then you make 4 more: LS Open, LS High, LS Low, LS Close. And all of these are of type number.

And then, for example, the “List to Shift” for LS Open is LS Stock Price's each item's Open. For LS High, the source would be LS Stock Price's each item's High. Etc.

And now you have 4 parallel lists of numbers that represent those values and you can easily operate on them using PROCESS List (in any of those List Shifters, or even in an entirely different one).

I describe this and link to an example a couple of replies up the thread. See this reply: List Shifter: Reverse, Rotate, Swap and ITERATE (Loop) Over Bubble Lists | Now at v1.4: Adds Numeric Option, GET INDEX Action - #438 by keith

The example should help you understand how you get multiple lists into PROCESS List so that you can operate on them (as in the case of wanting to do something with a list of HIGHs and a list of LOWs).

1 Like

Thank you so much @keith, that is exactly what I need explained. Having done some quick tests I see that it’s working as expected.

And yes, the stock data is the result of an API call. Now that I understand how to use LS Type List Constant I can move on from there.

Thanks again.

I did see your question about rounding. I think you figured out that you can round as part of displaying your values. But you could also do that in PROCESS List, if desired.

Process list does support Math.round(x). In JavaScript, to round a number to two decimal places, we can do Math.round(num * 100) / 100.

To do that in PROCESS List, we would need to use three of the steps, first, take our result item and multiply it by 100, second do Math.round(x) on the result, and third take that second result and divide it by 100.

(So, you can do it, but it’s probably not necessary as the numbers can simply be formatted with 2 decimal places when presented.)

1 Like

Hi, @keith , great app and thank you very much!
I’m having trouble with the listshifter when it’s hidden, is it normal that when the plugin is hidden on page, my RG is also hidden?
Any way to keep the RG when plug in is not visible?


Hi @keith ,

Hi Keith, is it possible to simply set up the PROCESS mechanism so it can do a quick TRUE/FALSE test between two values, then proceed to the next operation if true?

For example if A > B = TRUE, then STEP 2: perform some math, or if A > B = FALSE, then skip everything and iterate to the next number.

If so, how would that look?

Thanks

Yeah, element plugins can only function when they are visible. Don’t hide List Shifter.

1 Like

Hey @underhill.dan, yes, this is what the “Push/Sum/Set Only If” option is for in PROCESSED List Step 2 and higher.

Note that the results of any Step in List Shifter can be of various types and booleans are one of those. So, you can have a step that does an evaluation and the result of that step will be true or false. (Note that the results of a step don’t have to be scalars, but can also be arrays.)

Then, in a subsequent step, you can refer to that boolean evaluation and use it to say “do the push/sum/set part of the step only if RSx” which means “do the push/sum/set only if RSx is true”.

So, building on my original listwise multiplication example, here’s a simple variation where we only push the multiplied result to the Processed List if that result is greater than 50. We use 3 steps, like this:

Step 1:
Multiply “a” times “b”. Note that we do not immediately push the value to the processed list, it just stays available to us as RS1 (“Result of Step 1”):

Step 2:
Evaluate RS1 > 50. This will create RS2, which will be true if RS1 is greater than 50, or false if RS1 is less than 50:

Step 3:
Push RS1 to Processed List only if RS2 is true. Here, we refer back to Result of Step 1 (when there is no Operator, what we are saying is “just get me this value”). RS3 is now the same value as RS1. And now we set “Push RS3 to Processed List” to yes, but then we add the caveat, only do this if Result of Step 2 is true:

Example: https://list-shifter-demo.bubbleapps.io/version-test/only_if_feature?debug_mode=true

You will note that there are several other options in the “Only If” dropdown. These include any of the values of previous steps, “Not First Iteration”, “Not Last Iteration”, and then the negated boolean values of previous steps (for example, if we selected !Result Step 2, we would be saying, "push RS3 to the Processed List only if RS2 is false).

1 Like

Hi @keith,

Thank you again so much for your great explanations and help (mucho coffee rewards forthcoming).

To key off your example above where I only need to run something IF a certain condition is met, I need some further clarification. Here is my exact situation:

I have 3 ListShifters: LS OPEN, LS CLOSE, LS HIGH

I need to perform the following:

IF LS OPEN - LS CLOSE is less than zero (a negative number), THEN
calculate LS HIGH - LS CLOSE instead.

I can do the first part fine, but then configuring PROCESS to do the second part is tripping me up. Any guidance is greatly appreciated. :slight_smile:

What you’re looking for is just the absolute value of the subtraction. (To wit: 5 - 3 = 2 … 3 - 5 = -2). Absolute value of 2 or -2 are both 2.

But I see that I neglected to implement Math.abs() in PROCESS List. That’s a bummer as it would then just be a two-step routine (step one subtract one number from the other, step two take the absolute value).

But no biggie, there many other ways to do that. Here’s one of them:

Step 1: high - low
Step 2: low - high
Step 3: Result Step 1 | Math.max(x y) | Result Step 2
Push RS3 to Processed List

Should work fine.

Thanks Keith, what I’m really looking to do is to say “If the value of LS OPEN - LS CLOSE is negative, then (ignore that value and do the following) calculate the result of LS HIGH - LS CLOSE instead.” Then push THAT result onto the proccessed list.

I just want to use the answer from the first equation to determine IF we run the second equation between those other lists. I don’t ever want to push the result of the first equation onto any processed list. That result is used to guide whether we run the second equation… and when we do we push THAT result onto the processed list.

Hopefully that makes sense. If need be we can schedule a time to talk.