Formula to Separate Concatenated Items?

Hi Albert

Essentially, I just used Concatenate() to build the JSON String:

Because this particular case then involved using a rollup to get all of these values for a particular client / project I then used Substitute to format the multiple values correctly:

I hope this helps!

Julian

This is amazing! Thank you for a quick response.

Hi! I’m trying to something similar. I have a string of URLs that I would like to separate so they are their own column in Airtable.

Ie
Www.test1com, www.test2com, www.test3com

To become three separate columns in Airtable?

Can anyone help? @Julian_Kirkness @Arlo_Haskell

Hi Annie

Can I ask - are there always 3 URL - or does it vary?

Julian

Hi Julian! Thanks for the followup. It might vary. The range is anywhere
from 1 to 20.

Cheers.
Annie

Would you then be looking to populate 20 columns? Would these be newly created columns whenever a new URL was encountered, or would a set of columns — {NewURL01}, {NewURL02}, and so on — possibly contain a range of URLs that vary from record to record?

Hi @W_Vann_Hall - Yes, I would be looking to then populate 1-20 columns where each column is the newly separated item. The intent is then to create 1-20 Airtable views to trigger an email notification.

Suggestions? Thoughts? Apprec the help in advance!

Tagging @Julian_Kirkness for the earlier response from Saturday. Thanks in advance for the help!

Hi Annie

At the moment, I can’t immediately think of a way to achieve this in Airtable although it may be possible with Zapier (or code via the API).

However, I wonder if there’s any other way - are the URLs being populated in a Rollup field for example - in which case could something be done in the underlying records.

Wherever possible I try to work with the database and get it to do as much of the work as possible.

Julian

Well, it can be done, but it will probably be ugly! :wink:

I’d first create a field called something like {URLCount} with the following formula

LEN({URLString})-LEN(SUBSTITUTE({URLString},',',''))+1

(That’s @Simon_Brown’s clever trick to count the number of [whatevers] in a list of [whatevers]. It can be hard to deconstruct, but it takes the length of the original string and subtracts from it the length of the string with all the separation-character commas removed — essentially counting the number of commas — to which it then adds 1 to account for the final element in the list, which lacks a trailing comma.)

After that, I’d define my 20 extracted URL fields, each with a variant of this formula:

deconcatenate_example
So for {URL3} the formula would be

IF(
    {URLCount}>=3,
    MID(
        {URLString}&',',
        FIND(
            ',',
            {URLString},
            (LEN({URL1})+2)
            )+1,
        FIND(
            ',',
            {URLString}&',',
            (LEN({URL1})+2)+
                (LEN({URL2})+2)
            )-FIND(
                ',',
                {URLString}&',',
                (LEN({URL1})+2)
                )-1
            )
    )

and for {URL4}

IF(
    {URLCount}>=4,
    MID(
        {URLString}&',',
        FIND(
            ',',
            {URLString},
            (LEN({URL1})+2)+
                (LEN({URL2})+2)
            )+1,
        FIND(
            ',',
            {URLString}&',',
            (LEN({URL1})+2)+
                (LEN({URL2})+2)+
                (LEN({URL3})+2)
            )-FIND(
                ',',
                {URLString}&',',
                (LEN({URL1})+2)+
                    (LEN({URL2})+2)
                )-1
            )

As you can imagine, by the time you get to {URL20}, those chained LEN() statements will be pretty long. (And, yes, it would probably be better practice and more efficient to sum the LEN()s and then add 2 * the number of LEN()'s, but adding 2 to each statement individually is far more copy-and-paste-friendly.)

[BTW, Airtable will let you compose formulas offline — under Windows, I personally recommend Notepad++ for its automatic indentation and parenthesis-matching features — and then copy-and-paste indented code into the formula field. What’s more, if you copy-and-paste the formula from Airtable back into Notepad++ to correct or modify, the indentation is maintained. Offline composition makes creating behemoths like these far more manageable.]

Obviously, the formulas for {URL1} and {URL2} will be a little different; I’m including them for completeness’ sake.

{URL1}:

IF(
    {URLCount}>=1,
    MID(
        {URLString}&',',
        1,
        FIND(
            ',',
            {URLString}&',',
            1
            )-1
        )
    )

{URL2}:

IF(
    {URLCount}>=2,
    MID(
        {URLString}&',',
        FIND(
            ',',
            {URLString},
            0
            )+1,
        FIND(
            ',',
            {URLString}&',',
            (LEN({URL1})+2)
            )-FIND(
                ',',
                {URLString}&',',
                0
                )-1
            )
    )

I’ve put together a little demo of this code (up through {URL4}, only — didn’t want to have all the fun :wink: ) here.

Hope this helps!

1 Like

<weasel words>
I probably should mention I have no idea why this works. Obviously, it’s highly dependent upon the order in which fields are evaluated, and that sort of scheduling issue has been the bane of system and compiler developers ever since computers. Airtable may very well have a wicked smart scheduling routine busily at work behind the scenes, protecting reckless fools like me from the perils of what we don’t know we don’t know, but as I’ve not seen any comments as to that being the case, I should caveat the previous reply by saying you should watch for possible failures of the algorithm or, more likely, for repeated display of the base to return different results. Again, this caution does not reflect any concern about or reluctance to use Airtable but just an acknowledgement that I have done something here that has been known to trip up some platforms or languages.
</weasel words>

You are amzing! Thank you so much for this help @W_Vann_Hall

@W_Vann_Hall

This post and your example base have been BEYOND helpful. But I’m struggling to debug my code for “URLs” 5 and 6… Could you share examples of those formulas or help me find my errors in the below (for “Style Name 5”)?

IF(
    {Comma Count}>=5,
    MID(
        {Style Name}&'\n',
        FIND(
            '\n',
            {Style Name},
            	(LEN({Style Name 1})+2)+
                (LEN({Style Name 2})+2)+
		(LEN({Style Name 3})+2)
            )+1,
        FIND(
            '\n',
            {Style Name}&'\n',
            	(LEN({Style Name 1})+2)+
                (LEN({Style Name 2})+2)+
                (LEN({Style Name 3})+2)+
		(LEN({Style Name 4})+2)
            )-FIND(
                '\n',
                {Style Name}&'\n',
                (LEN({Style Name 1})+2)+
                (LEN({Style Name 2})+2)+
 		(LEN({Style Name 3})+2)
                )-1
            )

OK, mighta gotten it:

IF( {Comma Count}>=5, 
MID( {Style Name}&'\n', 
FIND( '\n', {Style Name}, 
(LEN({Style Name 1})+2)+ 
(LEN({Style Name 2})+2)+ 
(LEN({Style Name 3})+2) )+1, 
FIND( '\n', {Style Name}&'\n', 
(LEN({Style Name 1})+2)+ 
(LEN({Style Name 2})+2)+ 
(LEN({Style Name 3})+2)+ 
(LEN({Style Name 4})+2) )
-FIND( '\n', {Style Name}&'\n', 
(LEN({Style Name 1})+2)+ 
(LEN({Style Name 2})+2)+ 
(LEN({Style Name 3})+2) )-1 ) )

Yes, that works for the fifth field. Here’s the syntax for the sixth:

IF( {Comma Count}>=6, 
MID( {Style Name}&'\n', 
FIND( '\n', {Style Name}, 
(LEN({Style Name 1})+2)+ 
(LEN({Style Name 2})+2)+ 
(LEN({Style Name 3})+2)+ 
(LEN({Style Name 4})+2) )+1, 
FIND( '\n', {Style Name}&'\n', 
(LEN({Style Name 1})+2)+ 
(LEN({Style Name 2})+2)+ 
(LEN({Style Name 3})+2)+ 
(LEN({Style Name 4})+2)+ 
(LEN({Style Name 5})+2) )
-FIND( '\n', {Style Name}&'\n', 
(LEN({Style Name 1})+2)+ 
(LEN({Style Name 2})+2)+ 
(LEN({Style Name 3})+2)+ 
(LEN({Style Name 4})+2) )-1 ) )

I wanted to apologize for not getting back to you; I’m guessing I experienced a browser crash part-way through my reply, since when I opened this thread, I was greeted by an edit window containing a partial response. (Anyone know if Discourse allows one to display any unfinished drafts on file?) I see you didn’t need me, thankfully.

I guess I’m one of those Santayana said were condemned to repeat the past, as I essentially recreated this post and base from scratch a couple of weeks ago. I haven’t tried a point-by-point comparison, but I have a feeling the newer version is a slightly more elegant solution (or, at least, explained more nicely).

Note in {URL4} example there is one closing ‘)’ missing at the very bottom.

I posted an alternative solution in this topic.

I am also posting the formulas here in order to

  • acknowledge that this topic was the inspiration for my solution
  • highlight aspects of my refactoring that would have cluttered up the other topic
  • make it easier to continue this conversation (where the formula writers are)

While this solution was inspired by W_Vann_Hall’s post, the formulas are actually quite different.

  • This solution does not need a field to count the number of items in the list, which reduces the complexity of the formulas. (The initial IF statement is not needed.)
  • It uses a combination of LEFT and RIGHT functions, instead of the MID function. When building the functions, it was easier for me to mentally picture using the RIGHT function to identify everything remaining in the string, and then using the LEFT function to pick off the first item.
  • It also reduces the overall amount and complexity of code by
    • Using the CONCATENATE function instead of summing multiple LEN functions.
    • Subtracting a single number that increases for each item, rather than repeatedly adding 2 for each previous item.

Here is a screen shot of the sample base.

Here is the formula for the field {Item1}.

IF( FIND(",", {List}),
  LEFT({List},
    FIND(",", {List})-1
  ),
  {List}
)

Here is the formula for the field {Item2}:

LEFT(
  RIGHT({List},
    LEN({List}) - LEN({Item1}) - 2
  ),
  FIND( ",", 
        RIGHT({List},
          LEN({List}) - LEN({Item1}) - 2
        ) & ","
      )-1
)

Here is the formula for the field {Item3}:

LEFT(
  RIGHT({List},
    LEN({List}) - LEN(CONCATENATE({Item1},{Item2})) -4
  ),
  FIND( ",", 
        RIGHT({List},
          LEN({List}) - LEN(CONCATENATE({Item1},{Item2})) -4
        ) & ","
      )-1
)

Here is the formula for the field {Item4}:

LEFT(
  RIGHT({List},
    LEN({List}) - LEN(CONCATENATE({Item1},{Item2},{Item3})) -6
  ),
  FIND( ",", 
        RIGHT({List},
          LEN({List}) - LEN(CONCATENATE({Item1},{Item2},{Item3})) -6
        ) & ","
      )-1
)

If you need more items, continue the pattern used for {Item3} and {Item4}:

  • add the next item to both of the CONCATENATE functions
  • subtract two more from the results of the LEN functions (e.g., for the 5th item, subtract 8; for the 6th item subtract 10, etc.) The number to subtract is determined by (2 x the item number) - 2. (Note you cannot put this in the actual formula because the item number is not a field.)
1 Like

Thank you, @kuovonne for your solution.
Do you think it may be extrapolated for undefined number of Items (max 10) and with the need to put each of them separately from the new line (after " \n ") in a long text field?

The formulas should work for far more than 10 items. Just keep following the pattern. I haven’t tried it for items with "\n ", but you could try it and let us know how it goes.

With the release of the new scripting block, I think that long workarounds like this will no longer be needed.