Strange behaviour with TEXTSPLIT which to me seems like a bug. Any other explanations?

Hi,

I am seeing strange behaviour with TEXTSPLIT which seems incorrect to me, particularly because the same calculations work when I use TEXTBEFORE and TEXTAFTER instead.

I am not looking to solve the particular examples posted, but rather some confirmation whether you agree that this is incorrect behaviour and a bug which should be reported to Microsoft.

The examples below are minimal example to reproduce the behaviour. I stumbled across this in some business logic which was giving incorrect results (and which was much more involved). I haven't been able to spot any pattern in the behaviour so I don't know how to protect myself against being bitten by this bug again in future (other than of course using TEXTBEFORE and TEXTAFTER instead, but that is more to type and also not always equivalent when you want to split into more than two fields).

Does anyone have any explanations or can point out my misconception before I report this as a bug to Microsoft?

Full Table of Examples

To simplify the formulas, I created the following APPLYCOL utility function. It basically functions like BYCOL but lets you return multi-row arrays instead of just a single row.

The APPLYCOL function is defined as follows:

a=1,b=2

Formula

Output

Expected

Status

Comment

=LET(
kvs, TEXTSPLIT($B$1,","),
out, APPLYCOL(kvs, LAMBDA(kv, TEXTSPLIT(kv,"="))),
ARRAYTOTEXT(out,1))

{"a","b"}

{"a","b";"1","2"}

FAIL

Why doesn't this work?

=LET(
kvs, TEXTSPLIT($B$1,","),
out, APPLYCOL(kvs, LAMBDA(kv,TEXTSPLIT(kv,,"="))),
ARRAYTOTEXT(out,1))

{"a","b"}

{"a","b";"1","2"}

FAIL

Or at least this?

=LET(
kvs, TEXTSPLIT($B$1,","),
out, APPLYCOL(kvs, LAMBDA(kv, TOCOL(TEXTSPLIT(kv,"=")))),
ARRAYTOTEXT(out,1))

{"a","b"}

{"a","b";"1","2"}

FAIL

Or this?

=LET(
out, TRANSPOSE(TEXTSPLIT($B$1,"=",",")),
ARRAYTOTEXT(out,1))

{"a","b";"1","2"}

{"a","b";"1","2"}

PASS

This works but doesn't scale to more rows.

=LET(
kvs, {"a=1","b=2"},
out, VSTACK(TEXTBEFORE(kvs,"="),TEXTAFTER(kvs,"=")),
ARRAYTOTEXT(out,1))

{"a","b";"1","2"}

{"a","b";"1","2"}

PASS

This works and led me to discover the next one.

=LET(
kvs, TEXTSPLIT($B$1,","),
out, VSTACK(TEXTBEFORE(kvs,"="),TEXTAFTER(kvs,"=")),
ARRAYTOTEXT(out,1))

{"a","b";"1","2"}

{"a","b";"1","2"}

PASS

Bizarrely this works!

=LET(
kvs, TEXTSPLIT($B$1,","),
out, TEXTSPLIT(kvs,,"="),
ARRAYTOTEXT(out,1))

{"a","b"}

{"a","b";"1","2"}

FAIL

But this doesn't.

=LET(
kvs, HSTACK(TEXTBEFORE($B$1,","),TEXTAFTER($B$1,",")),
out, TEXTSPLIT(kvs,,"="),
ARRAYTOTEXT(out,1))

{"a","b"}

{"a","b";"1","2"}

FAIL

Why doesn’t this work even though we're splitting by row delimiter?

=LET(
kvs, HSTACK(TEXTBEFORE($B$1,","),TEXTAFTER($B$1,",")),
out, APPLYCOL(kvs, LAMBDA(kv, TEXTSPLIT(kv,,"="))),
ARRAYTOTEXT(out,1))

{"a","b"}

{"a","b";"1","2"}

FAIL

Why doesn’t this work even though we're splitting by row delimiter?

=LET(
kvs, HSTACK(TEXTBEFORE($B$1,","),TEXTAFTER($B$1,",")),
out, VSTACK(TEXTBEFORE(kvs,"="),TEXTAFTER(kvs,"=")),
ARRAYTOTEXT(out,1))

{"a","b";"1","2"}

{"a","b";"1","2"}

PASS

The fact that this works seems to really point the finger at TEXTSPLIT as the problem.

=LET(
kvs, TEXTSPLIT($B$1, ","),
keys, MAP(kvs, LAMBDA(kv, INDEX(TEXTSPLIT(kv, "="), 1))),
vals, MAP(kvs, LAMBDA(kv, INDEX(TEXTSPLIT(kv, "="), 2))),
out, VSTACK(keys,vals),
ARRAYTOTEXT(out,1))

{"a","b";"1","2"}

{"a","b";"1","2"}

PASS

Here TEXTSPLIT works again. Why? Because it's inside a MAP?

=LET(
kvs, TEXTSPLIT($B$1,","),
out, APPLYCOL(kvs, LAMBDA(kv, TOCOL(TEXTSPLIT(kv,"=")))),
ARRAYTOTEXT(out,1))

{"a","b"}

{"a","b";"1","2"}

FAIL

Why doesn't this work when the previous line worked?

=LET(
kvs, TEXTSPLIT($B$1,","),
out, APPLYCOL(kvs, LAMBDA(kv, VSTACK(TEXTBEFORE(kv,"="),TEXTAFTER(kv,"=")))),
ARRAYTOTEXT(out,1))

{"a","b";"1","2"}

{"a","b";"1","2"}

PASS

=LET(
out, APPLYCOL({"a=1","b=2"}, LAMBDA(kv, VSTACK(TEXTBEFORE(kv,"="),TEXTAFTER(kv,"=")))),
ARRAYTOTEXT(out,1))

{"a","b";"1","2"}

{"a","b";"1","2"}

PASS

=LET(
kvs, TEXTSPLIT($B$1,","),
out, APPLYCOL(kvs, LAMBDA(kv,TOCOL( HSTACK(TEXTBEFORE(kv,"="),TEXTAFTER(kv,"="))))),
ARRAYTOTEXT(out,1))

{"a","b";"1","2"}

{"a","b";"1","2"}

PASS

=LET(
kvs, TEXTSPLIT($B$1,","),
out, MAKEARRAY(2, 2, LAMBDA(r,c, INDEX(TEXTSPLIT(INDEX(kvs,c),"="),r))),
ARRAYTOTEXT(out,1))

{"a","b";"1","2"}

{"a","b";"1","2"}

PASS

Works as expected.

=LET(
kvs, TEXTSPLIT($B$1,","),
txts, MAP(kvs, LAMBDA(kv, ARRAYTOTEXT(TEXTSPLIT(kv,,"="), 0))),
xmlsplit, LAMBDA(text,delimiter, FILTERXML("<t><s>" & SUBSTITUTE(text, delimiter, "</s><s>") & "</s></t>", "//s")),
out, APPLYCOL(txts, LAMBDA(txt, ARRAYTOTEXT(xmlsplit(txt, ", "),0))),
ARRAYTOTEXT(out,1))

{"a","b"}

{"a","b";"1","2"}

FAIL

I'm surprised even this doesn't work.

=LET(
kvs, HSTACK(TEXTBEFORE($B$1,","),TEXTAFTER($B$1,",")),
out, APPLYCOL(kvs, LAMBDA(kv, VSTACK(TEXTBEFORE(kv,"="),TEXTAFTER(kv,"=")))),
ARRAYTOTEXT(out,1))

{"a","b";"1","2"}

{"a","b";"1","2"}

PASS

=LET(
kvs, TEXTSPLIT($B$1, ","),
out, APPLYCOL(kvs, LAMBDA(kv, COUNTA(TEXTSPLIT(kv, "=")))),
ARRAYTOTEXT(out,1))

{1,1}

{2,2}

FAIL

It's weird that with APPLYCOL the COUNTA is only seing a 1-element array.

=LET(
kvs, TEXTSPLIT($B$1, ","),
out, MAP(kvs, LAMBDA(kv, COUNTA(TEXTSPLIT(kv, "=")))),
ARRAYTOTEXT(out,1))

{2,2}

{2,2}

PASS

With MAP, COUNTA sees a 2-element array as expected.

Excel Version

|
Answer
Answer

Keep it simpler. Try:

=TEXTSPLIT({"a=1"},"=")

You will just get "a" as the output because you are asking it technically to output a 2D array even if the number of rows (or columns) is actually 1, and it won't do that because it might be a jagged array. Instead it simply returns the first row/col of results.

Perhaps a decision was made that the overhead of verifying the dimensions of the output wasn't justified, or simply that it would be inconsistent for it to work one way in some circumstances and another way in others.

Whatever the reasoning, the simple answer is not to pass an array as the first argument to TEXTSPLIT. I do not believe that MS would accept that it is a bug.

Regards,
Rory

1 person found this reply helpful

·

Was this reply helpful?

Sorry this didn't help.

Great! Thanks for your feedback.

How satisfied are you with this reply?

Thanks for your feedback, it helps us improve the site.

How satisfied are you with this reply?

Thanks for your feedback.

 
 

Question Info


Last updated March 1, 2024 Views 75 Applies to: