Sort the numbers in given strings and leave the non numbers as they are. Sorted numbers should come first in the string followed by unsorted non numbers. Note – “8” is a number not a non-number.
📌 Challenge Details and Links
ExcelBI Excel Challenge Number: 226
Challenge Difficulty: ⭐️⭐️
📥Download Sample File
📥Link to the solutions on LinkedIn
Solving the challenge of Sort Numbers Leave Text with Power Query
Power Query solution 1 for Sort Numbers Leave Text, proposed by Omid Motamedisedeh:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
Custom1 = Table.TransformColumns(
Source,
{
"Strings",
(o) =>
Text.Combine(
List.Sort(
Text.Split(o, ","),
each try Number.From(Text.Replace(_, """", "")) / 100 otherwise Text.PositionOf(o, _)
),
","
)
}
)
in
Custom1
Power Query solution 2 for Sort Numbers Leave Text, proposed by Bo Rydobon 🇹🇭:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
Ans = Table.TransformRows(
Source,
each
let
l = Text.Split([Strings], ", ")
in
Text.Combine(
List.Sort(
l,
each try Number.From(Text.Replace(_, """", "")) otherwise 10 + List.PositionOf(l, _)
),
", "
)
)
in
Ans
Power Query solution 3 for Sort Numbers Leave Text, proposed by Zoran Milokanović:
let
Source = Excel.CurrentWorkbook(){[Name = "Input"]}[Content],
S = Table.TransformRows(
Source,
each
let
t = Text.Split([Strings], ", ")
in
Text.Combine(
List.Transform(
List.Sort(
List.Positions(t),
(p) =>
let
n = Character.ToNumber(Text.Remove(t{p}, """"))
in
if n < 58 then n else 58 + List.PositionOf(List.FirstN(t, p + 1), t{p}, 1)
),
each t{_}
),
", "
)
)
in
S
Power Query solution 4 for Sort Numbers Leave Text, proposed by Zoran Milokanović:
let
Source = Excel.CurrentWorkbook(){[Name = "Input"]}[Content],
S = Table.TransformRows(
Source,
each
let
t = Text.Split([Strings], ", "),
c = List.Select(t, each List.Contains({"a" .. "z"}, _)),
n = List.Difference(t, c)
in
Text.Combine(List.Sort(n, each Text.Remove(_, """")) & c, ", ")
)
in
S
Power Query solution 5 for Sort Numbers Leave Text, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
Sol = Table.AddColumn(Source, "Answer", each
let
a = Text.Split([Strings], ", "),
b = List.Sort(List.RemoveMatchingItems(a, {"a".."z"}), each Text.Remove(_, """")),
c = b&List.RemoveMatchingItems(a,b)
in Text.Combine(c, ", "))[[Answer]]
in
Sol
En caso que hubiesen mayúsculas, habría que utilizar Comparer.OrdinalIgnoreCase en "b".
Power Query solution 6 for Sort Numbers Leave Text, proposed by Luan Rodrigues:
let
Fonte = Tabela1,
res = Table.AddColumn(
Fonte,
"Personalizar",
each [
a = List.Select(
Splitter.SplitTextByAnyDelimiter({"a" .. "z", ",", " "}, QuoteStyle.None)([Strings]),
each _ <> ""
),
b = List.Zip({List.Transform(a, each Text.Select(_, {"0" .. "9"})), a}),
c = List.ReplaceMatchingItems(List.Sort(List.Transform(b, each _{0})), b),
d = Text.Combine(c & Text.ToList(Text.Select([Strings], {"a" .. "z"})), ", ")
][d]
)
in
res
Power Query solution 7 for Sort Numbers Leave Text, proposed by Sergei Baklan:
let
Source = Excel.CurrentWorkbook(){[Name = "Strings"]}[Content],
tbl = Table.PromoteHeaders(Source, [PromoteAllScalars = true]),
result = Table.AddColumn(
tbl,
"Answer",
each [
items = Text.Split([Strings], ","),
numbers = List.Sort(List.Select(items, (s) => Value.Is(Value.FromText(s), Number.Type))),
texts = List.Select(items, (s) => Value.Is(Value.FromText(s), Text.Type)),
result = Text.Combine(List.Transform(numbers & texts, Text.Trim), ", ")
][result],
type text
)
in
result
Solving the challenge of Sort Numbers Leave Text with Excel
Excel solution 1 for Sort Numbers Leave Text, proposed by Bo Rydobon 🇹🇭:
=MAP(A2:A8,LAMBDA(a,LET(t,TEXTSPLIT(a,", "),ARRAYTOTEXT(SORTBY(t,--SUBSTITUTE(t,"""",))))))
Excel solution 2 for Sort Numbers Leave Text, proposed by Rick Rothstein:
=MAP(A2:A8,LAMBDA(x,LET(t,TEXTSPLIT(x,", "),TEXTJOIN(", ",,SORTBY(t,0+SUBSTITUTE(t,"""",))))))
Excel solution 3 for Sort Numbers Leave Text, proposed by John V.:
=MAP(A2:A8,LAMBDA(x,ARRAYTOTEXT(SORTBY(TEXTSPLIT(x,", "),IFERROR(--TEXTSPLIT(SUBSTITUTE(x,"""",),", "),9)))))
Excel solution 4 for Sort Numbers Leave Text, proposed by محمد حلمي:
=MAP(A2:A8,LAMBDA(a,LET(e,TEXTSPLIT(a,
{", ",""""}),TEXTJOIN(", ",,SORTBY(e,--e)))))
Excel solution 5 for Sort Numbers Leave Text, proposed by Kris Jaganah:
=MAP(A2:A8,LAMBDA(x,LET(a,TEXTSPLIT(x,,", "),b,IF(LEN(a)>1,MID(a,2,1),a),c,SORT(FILTER(b,ISNUMBER(-b),"")),d,FILTER(b,ISERR(-b),""),TEXTJOIN(", ",1,VSTACK(XLOOKUP(c,b,a,""),d)))))
Excel solution 6 for Sort Numbers Leave Text, proposed by Julian Poeltl:
=MAP(A2:A8,LAMBDA(S,LET(SP,TEXTSPLIT(S,,", "),N,--SUBSTITUTE(SP,"""",""),E,ISERR(N),TEXTJOIN(", ",,VSTACK(IFERROR(SORTBY(FILTER(SP,NOT(E)),FILTER(N,NOT(E))),""),IFERROR(FILTER(SP,E),""))))))
Excel solution 7 for Sort Numbers Leave Text, proposed by Timothée BLIOT:
=MAP(A2:A8, LAMBDA(z, LET(A,TEXTSPLIT(z,", "),B,MAP(A,LAMBDA(x,LET(D, SUBSTITUTE(x,"""",)*1,IF(ISNUMBER(D),D,10)))),ARRAYTOTEXT(SORTBY(A,B)))))
Excel solution 8 for Sort Numbers Leave Text, proposed by Hussein SATOUR:
=MAP(A2:A8, LAMBDA(z, ARRAYTOTEXT(LET(a, TEXTSPLIT(z,, ", "), x, ISNUMBER(--a), y, NOT(ISNUMBER(--SUBSTITUTE(a, """", ""))), b, FILTER(a, (x) + (NOT(ISERR(FIND("""", a))))), IFS(SUM(--x) = COUNTA(a), SORT(--a), SUM(--y)=COUNTA(a), a, TRUE, VSTACK(SORTBY(b, --SUBSTITUTE(b, """", "")), FILTER(a, y)))))))
Excel solution 9 for Sort Numbers Leave Text, proposed by Oscar Mendez Roca Farell:
=MAP(A2:A8, LAMBDA(a, LET(_w, TEXTSPLIT(a, ,", "), ARRAYTOTEXT( DROP(ORDER(HSTACK(--SUBSTITUTE(_w,"""", ),_w)), ,1)))))
Excel solution 10 for Sort Numbers Leave Text, proposed by Sunny Baggu:
=MAP(
A2:A8,
LAMBDA(a,
LET(
_ts, TEXTSPLIT(a, , ", "),
_t, SUBSTITUTE(_ts, """", ""),
_s, SORT(_t + 0),
ARRAYTOTEXT(SORTBY(_ts, _t + 0))
)
)
)
Excel solution 11 for Sort Numbers Leave Text, proposed by JvdV -:
=MAP(A2:A8,LAMBDA(x,LET(y,TEXTSPLIT(x,", ",),TEXTJOIN(", ",,SORTBY(y,--MID(y&y,2,1))))))
Excel solution 12 for Sort Numbers Leave Text, proposed by Tolga Demirci, PMP, PMI-ACP, MOS-Expert:
=MAP(A2:A8;B2:B8;LAMBDA(e;o;LET(y;TEXTSPLIT(e;;{", ";""""});IF(SUM(IFERROR(y+0;1))=COUNTA(y);o;IF(COUNTA(UNIQUE(ISNUMBER(IFERROR(VALUE(y);""))))=1;TEXTJOIN(", ";;SORT(VALUE(y);;1));TEXTJOIN(", ";;VSTACK(LET(x;IFERROR(SORT(y+0;;1);"");FILTER(x;x<>""));LET(p;SUBSTITUTE(y;IFERROR(y+0;"");"";1);FILTER(p;p<>"")))))))))
Excel solution 13 for Sort Numbers Leave Text, proposed by Pieter de Bruijn:
=MAP(A2:A8,LAMBDA(x,LET(y,TEXTSPLIT(x,", "),a,SORT(TOCOL(FILTER(y,ISNUMBER(--SUBSTITUTE(y,"""",""))),3)),b,SORTBY(a,SUBSTITUTE(a,"""","")),c,TOCOL(REPT(y,IF(ISERR(--SUBSTITUTE(y,"""","")),1,NA())),3),d,VSTACK(IFERROR(b,""),IFERROR(c,"")),ARRAYTOTEXT(TOCOL(IF(d="",NA(),d),3)))))
Wow, reading below this could be reduced to =MAP(A2:A8,LAMBDA(a,LET(e,TEXTSPLIT(a,
{", ",""""}),ARRAYTOTEXT(SORTBY(e,--e)))))
Excel solution 14 for Sort Numbers Leave Text, proposed by Giorgi Goderdzishvili:
=LET(
s,SUBSTITUTE(A2,"""",""),
splt,IFERROR(--TEXTSPLIT(s,", "),TEXTSPLIT(s,", ")),
isSymb,MAP(TEXTSPLIT(A2,", "),LAMBDA(s,ISNUMBER(SEARCH("""",s)))),
seq,SEQUENCE(,COUNTA(splt)),
isnmb,ISNUMBER(splt),
nmbSrt,SORT(FILTER(splt,isnmb),1,1,TRUE),
text,FILTER(splt,NOT(isnmb)),
final,HSTACK(nmbSrt,text),
indexing,INDEX(isSymb,1,XMATCH(final,splt)),
finalMap,MAP(indexing,final,LAMBDA(i,f,IF(i,""""&f&"""",f))),
checking,VSTACK(splt,final,isSymb),
finaler,TEXTJOIN(", ",TRUE,finalMap),
IFERROR(finaler,TEXTJOIN(", ",TRUE,IFERROR(nmbSrt,"")&IFERROR(text,""))))
Excel solution 15 for Sort Numbers Leave Text, proposed by Daniel Garzia:
=MAP(A2:A8,LAMBDA(l,LET(t,TEXTSPLIT(l,,", "),s,ROW(1:10)-1,TEXTJOIN(", ",,SORTBY(t,MAP(t,LAMBDA(x,IFERROR(LOOKUP(0,-SEARCH(s,x),s),""))))))))
Excel solution 16 for Sort Numbers Leave Text, proposed by Diarmuid Early:
=MAP(A2:A8,
LAMBDA(a,
LET(t,TEXTSPLIT(a,", "),
s,SORTBY(t,IFERROR(--SUBSTITUTE(t,"""",""),10)),
TEXTJOIN(", ",,s))))
Here t is the list of letters / numbers, s is t sorted in order*, TEXTJOIN puts it back together, and MAP applies the LAMBDA function that does all that to each input.
* Sorted by the number value if there is one, and 10 if there isn't, so non-numbers go at the end - and since SORTBY is a 'stable sort', all the values sorted by 10 (non-numbers) stay in their original order. If the numbers could be bigger than single-digit, you'd need a bigger constant for the non-numbers, which isn't super-elegant.
Bo's solution uses similar logic, but neatly uses the fact that SORTBY sorts errors later than numbers, so you actually don't need an IFERROR to achieve this result (also means that version would work for arbitrarily large input numbers)
&&&
