Forum Discussion
List.Generate, make behave like Accumulate or XL REDUCE
Hi,
my staring point was this, i wanted to accumute fieds to a record; so i used;
let
f = {List.Sum, List.Max, List.Average},
head = {"sum", "max", "avg"},
pos = {0, 1, 2},
val = {2, 3, 1, 5, 2, 1}
in
List.Accumulate(pos, [], (s, c) => Record.AddField(s, head{c}, Function.Invoke(f{c}, {val})))so simplifying you can have;
= let val = {12,21,34} , pos = {0,1,2},
head = {"a","b","c"}
in List.Accumulate( pos, [], (s,c)=> Record.AddField( s, head {c} , val {c} )) i have been trying to replaicate using generate; i have; but this accumutes a list of records, with the final being
what is wnated. is there a way to just generate each field ,
let
head = { "sum", "max", "avg"},
val = {2,3,1,5,2,1}
in
List.Generate(()=> [ x = 0, y = Record.AddField( [],head {0}, val{0} ) ],
each [x] < List.Count( head),
each [x = [x] + 1, y = Record.AddField( [y], head {x} , val {x} ) ],
each [y] )
i don't know if this is possible using Gen, perhaps putting it insided a record [ x = y, z = Listgenerate ] ?
any suggestions ? or as i think perhaps not doable ?
just to note, if anyone dashes of a quick repsonse i may not be able to respond until tomorrow.
Richard
and try this
let f = {List.Sum,List.Max, List.Average}, head = { "sum", "max", "avg"}, val = {2,3,1,5,2,1}, to= List.Generate(()=> [ i = 0, j = Record.AddField( [],head {i}, f{i}(val) ) ], (x)=> x[i] <= List.Count( head)-1, (x)=> [i = x[i] + 1, j = Record.AddField( [],head {i},f{i}(val)) ], (x)=>x[j]) in Record.Combine( to)
9 Replies
- Ahmedx
Super User
To get such a result, you need to use neither List.Accumulate nor List.Generate
let f = (x)=> {List.Sum(x), List.Max(x), List.Average(x)}, head = {"sum", "max", "avg"}, val = {2, 3, 1, 5, 2, 1}, to = Record.FromList(f(val), head) in to- Dicken
Post Prodigy
yes, i know , but i wanted to use LIst.Generate, can it be done ?
- Ahmedx
Super User
pls try
let f = {List.Sum, List.Max, List.Average}, head = {"sum", "max", "avg"}, n = List.Count(head)-1, val = {2, 3, 1, 5, 2, 1}, to = List.Generate(()=>[i=0, j=f{i}], (x)=> x[i]<=n, (x)=>[i= x[i]+1,j =f{i}], (x)=> Function.Invoke(x[j],{val})) in Record.FromList(to,head)
- Ahmedx
Super User
and try this
let f = {List.Sum,List.Max, List.Average}, head = { "sum", "max", "avg"}, val = {2,3,1,5,2,1}, to= List.Generate(()=> [ i = 0, j = Record.AddField( [],head {i}, f{i}(val) ) ], (x)=> x[i] <= List.Count( head)-1, (x)=> [i = x[i] + 1, j = Record.AddField( [],head {i},f{i}(val)) ], (x)=>x[j]) in Record.Combine( to)- Dicken
Post Prodigy
Thanks, will work through properly, i like anythiing that invvolvves records 😊
- Ahmedx
Super User
let f = {List.Sum, List.Max, List.Average}, head = {"sum", "max", "avg"}, val = {2, 3, 1, 5, 2, 1}, to = List.Generate( () => 0, (x) => x <= List.Count(f) - 1, (x) => x + 1, (x) => Record.FromList({f{x}(val)}, {head{x}}) ) in Record.Combine(to) ============================ let f = {List.Sum, List.Max, List.Average}, head = {"sum", "max", "avg"}, val = {2, 3, 1, 5, 2, 1}, to = List.Generate( () => 0, (x) => x <= List.Count(f)-1, (x) => x + 1, (x) => Record.AddField([],head {x}, f{x}(val) )) in Record.Combine(to)
- ronrsnfld
Super User
You can use List.Generate, but it seems cumbersome when what you want to do is accumulate results into a single record as List.Accumulate can do. List.Generate returns a List by design.
One method would be to wrap List.Generate inside List.Lastlet val = {12,21,34} , pos = {0,1,2}, head = {"a","b","c"}, res = List.Last(List.Generate( ()=>[idx=0, x=Record.AddField([],head{idx},val{idx})], each [idx] < List.Count(head), each [idx=[idx]+1, x=Record.AddField([x],head{idx},val{idx})], each Record.Combine({[x]}))) in resAnother method would be to return a List of Records and then combine them into a single record:
let val = {12,21,34} , pos = {0,1,2}, head = {"a","b","c"}, res = Record.Combine(List.Generate( ()=>[idx=0, x=Record.AddField([],head{idx},val{idx})], each [idx] < List.Count(head), each [idx=[idx]+1, x=Record.AddField([],head{idx},val{idx})], each [x])) in resPlease note that the most efficient method (within your constraints) would be by using List.Accumulate. Theoretically, Record.Combine(List.Generate(... should be more efficient than List.Last(List.Generate(... as one is only generating a single record for each "loop" in the former, and increasing numbers of records in the latter.
- lbendlin
Super User
Please provide sample data that covers your issue or question completely, in a usable format (not as a screenshot).
Do not include sensitive information. Do not include anything that is unrelated to the issue or question.
Please show the expected outcome based on the sample data you provided.
Need help uploading data? https://community.fabric.microsoft.com/t5/Community-Blog/How-to-provide-sample-data-in-the-Power-BI-Forum/ba-p/963216
Want faster answers? https://community.fabric.microsoft.com/t5/Desktop/How-to-Get-Your-Question-Answered-Quickly/m-p/1447523- Dicken
Post Prodigy
As far as i can tell there is no way to upload a copy of the file created, if there is could you plase let me know.