REDUCE function not working when feeding result of FILTER function. Why?

felixstraube

Well-known Member
Joined
Nov 27, 2023
Messages
897
Office Version
  1. 365
Platform
  1. Windows
  2. Web
Hi there.
I was scratching my head because of a REDUCE function that wouldn't work as expected. And I still can't figure out why. Can you help me?
It doesn't make much sense what the REDUCE function does, because it is not complete, but you'll see my problem.

Book1
ABCD
1Text01 #VALUE!
2Text02Text01
3Text02
4Text030
5Text03
6Text040
7Text05Text04
8Text05
9Text060
10Text07Text06
11Text08Text07
12Text08
13Text090
14Text10Text09
15Text10
Sheet1
Cell Formulas
RangeFormula
C1:C15C1=LET(t, A1:A100, maxrow, MAX(ROW(t)*(t<>"")), d, TAKE(t, maxrow), s, REDUCE("", d, LAMBDA(ini,x, VSTACK(ini,x))), s )
D1D1=LET(t, A1:A100, maxrow, MAX(ROW(t)*(t<>"")), d, FILTER(t, ROW(t)<=maxrow), s, REDUCE("", d, LAMBDA(ini,x, VSTACK(ini,x))), s )
Dynamic array formulas.


In column A, I will paste some text. The number of rows may change so I need to get the last row with data, and take or filter only those rows from start to the last with text (d is the filtered data). Then I feed d to the REDUCE function.
In C1, it works fine when I filter the data with TAKE. But the formula in D1, when I use FILTER, REDUCE will throws an #VALUE! error.

Here we can see that the content of d should be the same in both formulas:

Book1
ABCD
1Text01Text01Text01
2Text02Text02Text02
300
4Text03Text03Text03
500
6Text04Text04Text04
7Text05Text05Text05
800
9Text06Text06Text06
10Text07Text07Text07
11Text08Text08Text08
1200
13Text09Text09Text09
14Text10Text10Text10
Sheet1
Cell Formulas
RangeFormula
C1:C14C1=LET(t, A1:A100, maxrow, MAX(ROW(t)*(t<>"")), d, TAKE(t, maxrow), s, REDUCE("", d, LAMBDA(ini,x, VSTACK(ini,x))), d )
D1:D14D1=LET(t, A1:A100, maxrow, MAX(ROW(t)*(t<>"")), d, FILTER(t, ROW(t)<=maxrow), s, REDUCE("", d, LAMBDA(ini,x, VSTACK(ini,x))), d )
Dynamic array formulas.


But somehow the result of FILTER is different from the one of the TAKE function and REDUCE won't work.
Can you help me understand what is happening here?
 

Excel Facts

Format cells as time
Select range and press Ctrl+Shift+2 to format cells as time. (Shift 2 is the @ sign).
I don't really know why, but this seems to work:

Excel Formula:
=LET(t, A1:A100,
maxrow, MAX(ROW(t)*(t<>"")),
d, FILTER(t, ROW(t)<=maxrow),
s, REDUCE("", d, LAMBDA(ini,x, VSTACK(ini,T(x)))),
s
)
 
Upvote 0
Nice. Thank you. The question remains why this behavior.
And I add another weird behavior...

If I apply T() to the result of FILTER it works fine, if I do it to the result of TAKE, it returns only the first item:

Book1
ABCD
1Text01  
2Text02Text01Text01
3Text02
4Text03
5Text03
6Text04
7Text05Text04
8Text05
9Text06
10Text07Text06
11Text08Text07
12Text08
13Text09
14Text10Text09
15Text10
Sheet1
Cell Formulas
RangeFormula
C1:C2C1=LET(t, A1:A100, maxrow, MAX(ROW(t)*(t<>"")), d, T(TAKE(t, maxrow)), s, REDUCE("", d, LAMBDA(ini,x, VSTACK(ini,x))), s )
D1:D15D1=LET(t, A1:A100, maxrow, MAX(ROW(t)*(t<>"")), d, T(FILTER(t, ROW(t)<=maxrow)), s, REDUCE("", d, LAMBDA(ini,x, VSTACK(ini,x))), s )
Dynamic array formulas.


What am I missing here? I thought both functions return dynamic arrays. Why this different behavior?
 
Upvote 0
Rory's solution got me curious. This also seems to work:
Book1
IJ
1  
2Text01Text01
3Text02Text02
4
5Text03Text03
6
7Text04Text04
8Text05Text05
9
10Text06Text06
11Text07Text07
12Text08Text08
13
14Text09Text09
15Text10Text10
Sheet1
Cell Formulas
RangeFormula
I1:I15I1=LET(t, A1:A100, maxrow, MAX(ROW(t)*(t<>"")), d, TAKE(t, maxrow)&"", s, REDUCE("", d, LAMBDA(ini,x, VSTACK(ini,x))), s )
J1:J15J1=LET(t, A1:A100, maxrow, MAX(ROW(t)*(t<>"")), d, FILTER(t, ROW(t)<=maxrow)&"", s, REDUCE("", d, LAMBDA(ini,x, VSTACK(ini,x))), s )
Dynamic array formulas.

These coerce elements in d to text by appending "".
 
Upvote 0
TAKE returns one range/array (depending on what is passed to it) as it can only return one contiguous block. FILTER will return only an array. I would only use T() in the REDUCE, not on the overall resultant array.
 
Upvote 0
Thank you both for your time. Interesting what you found out.
It seems that the objects returned as an array by both functions are not exactly the same and are forced to a certain type (sting probably right?) when concatenated with "".
I think this is something similar to when we used SUBTOTAL with OFFSET to slice and array and apply the operation to one row at a time before excel 365. Or when you use something like this: N(IF({1},Elements)) to make INDEX work as expected in array formulas (like described here: Can Excel's INDEX function return array?)
I still don't know why these things work I just know they work. I would to love to learn why.
 
Upvote 0
I can only think it's something to do with the fact that in your example TAKE is passing a range, whereas FILTER is passing an array.
Interestingly the formula in E5 works, but not the one in E9
Fluff.xlsm
ABCDE
1Text01 #VALUE!
2Text02Text01
3Text02
4Text030
5Text030
6Text0400
7Text05Text040
8Text05
9Text060#VALUE!
10Text07Text06
11Text08Text07
12Text08
13Text090
14Text10Text09
15Text10
16
Sheet5
Cell Formulas
RangeFormula
C1:C15C1=LET(t, A1:A100,maxrow, MAX(ROW(t)*(t<>"")),d, TAKE(t, maxrow),s, REDUCE("", d, LAMBDA(ini,x, VSTACK(ini,x))),s)
D1D1=LET(t, A1:A100,maxrow, MAX(ROW(t)*(t<>"")),d, FILTER(t, ROW(t)<=maxrow),s, REDUCE("", d, LAMBDA(ini,x, VSTACK(ini,x))),s)
E5:E7E5=VSTACK(A5,A8,FILTER(A11:A14,A11:A14=""))
E9E9=VSTACK(A5,A8,INDEX(FILTER(A11:A14,A11:A14=""),1))
Dynamic array formulas.
 
Upvote 0
Interesting...apparently the blanks are the source of the problem? If the blank is converted to blank text by appending "" (as in E9) the error is avoided. Similarly, if the initial range is pre-processed (see col F) to convert "blanks" to "", the INDEX/FILTER component in VSTACK doesn't generate an error.
Book1
ABCDEFGHIJ
1Text01 #VALUE!Text01FALSE
2Text02Text01Text02FALSE
3Text02 TRUE
4Text030Text03FALSE
5Text030  TRUE
6Text0400Text04FALSE
7Text05Text040Text05FALSE
8Text05 TRUE
9Text0600Text06 FALSE
10Text07Text060Text07FALSE
11Text08Text07Text08FALSE
12Text08 TRUE
13Text090Text09FALSE
14Text10Text09Text10FALSE
15Text10TRUE
Sheet2
Cell Formulas
RangeFormula
C1:C15C1=LET(t, A1:A100,maxrow, MAX(ROW(t)*(t<>"")),d, TAKE(t, maxrow),s, REDUCE("", d, LAMBDA(ini,x, VSTACK(ini,x))),s)
D1D1=LET(t, A1:A100,maxrow, MAX(ROW(t)*(t<>"")),d, FILTER(t, ROW(t)<=maxrow),s, REDUCE("", d, LAMBDA(ini,x, VSTACK(ini,x))),s)
E5:E7E5=VSTACK(A5,A8,FILTER(A11:A14,A11:A14=""))
H5:H7H5=VSTACK(F5,F8,FILTER(F11:F14,F11:F14=""))
E9:E11E9=VSTACK(A5,A8,INDEX(FILTER(A11:A14,A11:A14="")&"",1))
H9:H11H9=VSTACK(F5,F8,INDEX(FILTER(F11:F14,F11:F14=""),1))
F1:F14F1=IF(ISBLANK(A1),"",A1)
J1:J15J1=ISBLANK(A1)
Dynamic array formulas.
 
Upvote 0
Interesting what you both found out.
Would it be correct to assume that the FILTER function has a bug?
If so should this be reported to Microsoft?
 
Upvote 0
I wouldn't call it a bug (especially not with filter), just that different functions handle empty cells differently.
 
Upvote 0

Forum statistics

Threads
1,224,823
Messages
6,181,182
Members
453,020
Latest member
Mohamed Magdi Tawfiq Emam

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top