cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
Highlighted
Solution Sage
Solution Sage

List.Unzip wanted

let suppose we have two lists for which I want to keep the correspondence in the order of the elements.
So if I change the order of the first one of the lists, the elements of the second list also arrange themselves in corresponding positions.
This is easily done using the List.Zip function.

But to get back two separate lists  you need a sort of List.Unzip function.

I imagined one based on the use of List.accumulate


How else can you do the reverse operation of List.Zip?

1 ACCEPTED SOLUTION

Accepted Solutions
Highlighted
Super User V
Super User V

Re: List.Unzip wanted

Hi @Rocco_sprmnt21 

 

You can zip it again, this will reverse the zip, or am I missing something?

= List.Zip( List.Zip( { { 1, 2 }, { 3, 4 }, { 5, 6 } } ) )

 

Best Regards,
Mariusz

If this post helps, then please consider Accepting it as the solution.

Please feel free to connect with me.
LinkedIn

 

View solution in original post

5 REPLIES 5
Highlighted
Super User V
Super User V

Re: List.Unzip wanted

Hi @Rocco_sprmnt21 

 

You can zip it again, this will reverse the zip, or am I missing something?

= List.Zip( List.Zip( { { 1, 2 }, { 3, 4 }, { 5, 6 } } ) )

 

Best Regards,
Mariusz

If this post helps, then please consider Accepting it as the solution.

Please feel free to connect with me.
LinkedIn

 

View solution in original post

Highlighted
Solution Supplier
Solution Supplier

Re: List.Unzip wanted

Hey @Rocco_sprmnt21 ,

I came up with this:

 

(ListGiven as list) as list =>
    let
        n = List.Count(ListGiven{0}),
        Acc =
            (ListGiven, k, n) =>
                let
                    ListK =
                        if k < n then
                            List.Transform(ListGiven, each _{k})
                        else
                            {},
                    NewList =
                        if k < n then
                            ListK & @Acc(ListGiven, k + 1, n)
                        else
                            ListK
                in
                    NewList,
        UnZipped = Acc(ListGiven, 0, n)
    in
        UnZipped

 

@Mariusz' answer is better and certainly easier. What I came up with just gives one list.

 




Feel free to connect with me:
LinkedIn

Highlighted
Solution Supplier
Solution Supplier

Re: List.Unzip wanted

Well,

 

Now I've made a tweaked List.Zip:

 

(ListGiven as list) as list =>
    let
        n =
            List.Max(
                List.Transform(
                    ListGiven,
                    each try List.Count(_) otherwise 1
                )
            ),
        GetK =
            (k) =>
                List.RemoveFirstN(
                    List.RemoveLastN(
                        List.Transform(
                            ListGiven,
                            each try _{k} otherwise null
                        ),
                        each _ = null
                    ),
                    each _ = null
                ),
        Zip =
            List.Generate(
                () =>
                    [
                        l =
                            List.RemoveFirstN(
                                List.RemoveLastN(
                                    List.Transform(
                                        ListGiven,
                                        each try _{0} otherwise _
                                    ),
                                    each _ = null
                                ),
                                each _ = null
                            ),
                        k = 1
                    ],
                each [k] <= n,
                each
                    [
                        l = GetK([k]),
                        k = [k] + 1
                    ],
                each [l]
            )
    in
        Zip

 

Contrary to List.Zip, it will also take single values, and cut leading and trailing nulls.

 

If you want to test it, you could name it fnListZip and use this:

 

let
    l = {1,3,5,7,9},
    k = {2,4,6},
    #"ListZip(l)" = List.Zip({l}),
    #"fnListZip(l)" = fnListZip({l}),
    #"ListZip(k,l)" = List.Zip({k,l}),
    #"fnListZip(k,l)" = fnListZip({k, l}),
    #"ListZip(ListZip(k,l))" = List.Zip(#"ListZip(k,l)"),
    #"fnListZip(fnListZip(k,l))" = fnListZip(#"fnListZip(k,l)"),
    #"ListZip(l,k,l)" = List.Zip({l, k, l}),
    #"fnListZip(l,k,l)" = fnListZip({l, k, l}),
    #"ListZip(ListZip(l,k,l))" = List.Zip(#"ListZip(l,k,l)"),
    #"fnListZip(fnListZip(l,k,l))" = fnListZip(#"fnListZip(l,k,l)"),
    NotReallyAListZip = {{1,2},{3,4},{5,6},7,9},
    #"ListZip(NotReallyAListZip)" = List.Zip(NotReallyAListZip),
    #"fnListZip(NotReallyAListZip)" = fnListZip(NotReallyAListZip),
    NotReallyAListZipB = {1,2,3,4,{5,"Here Is Something"},7,9},
    #"ListZip(NotReallyAListZipB)" = List.Zip(NotReallyAListZipB),
    #"fnListZip(NotReallyAListZipB)" = fnListZip(NotReallyAListZipB)
in
    #"fnListZip(NotReallyAListZipB)"

 

 

Best,

Spyros




Feel free to connect with me:
LinkedIn

Highlighted
Solution Sage
Solution Sage

Re: List.Unzip wanted

wow. this is the solution :-).

 

I was speculating on the InsertRanges

insertRanges 

 

function and I was thinking about situations of possible errors to manage.
In particular, I was thinking of cases where the different length of the vectors involved can lead to error.
Aside from these cases, a potential error situation occurred to me which also depends on the order of the elements in the vectors.
And on this I looked for ways to manage the situation.

 

la situazione si potrebbe presentare quando positions and ranges are, for instance,

{1, 5, 2} and  {22,55, {33,44}}.

 

image.png

 

image.png

 

 

I tryed to solve in the following way:

 

 

 

let
    Source = List.Sort(List.Zip({{1, 5, 2}, {22,55, {33,44}}}),each _{0})
in
    List.Accumulate(Source, {{},{}},(s,c)=>{s{0}&{c{0}},s{1}&{c{1}}})

 

 

But now there is not needs of news unzip function.

Highlighted
Solution Sage
Solution Sage

Re: List.Unzip wanted

...

in some respects the transformation carried out by the list.zip function on a set of lists is analogous (isomorphic?!) to that made by the table.transpose function on the set of columns of a table.
therefore like the transpose (transpose (T)) = T, should be also List.Zip (list.Zip (lists)) = lists

this property indicates yet another way of realizing the list.zip function through other functions

 

 

 

 

let
    ListZipUnZip = (lsts) =>  Table.ToColumns(Table.Transpose(Table.FromColumns(lsts)))
in
    ListZipUnZip

 

 

 

of course also the dual situation is valid.

if you wanted, for very personal reasons, to simulate the Table.Transpose function, you could use List.Zip

 

 

let
    transpose = (tab) =>  Table.FromColumns(List.Zip(Table.ToColumns(tab)))
in
    transpose

 

 

Helpful resources

Announcements
Meet the 2020 Season 2 Power BI Super Users!

Meet the 2020 Season 2 Power BI Super Users!

Find out who's part of the program this season, and welcome the new Super Users.

August 2020 Community Challenge: Can You Solve These?

August 2020 Community Challenge: Can You Solve These?

We're excited to announce our first cross-community 'Can You Solve These?' challenge!

July 2020 Community Highlights

July 2020 Community Highlights

Learn about the exciting things that happened in July.

Featured Data Story of The Month

Featured Data Story of The Month

All Data Stories Gallery contributions are reviewed for each month. We select a contribution and feature the community member the following month.

Power BI Dev Camp - Developing with .NET Core

Power BI Dev Camp - Developing with .NET Core

Learn how to develop custom web applications for Power BI using .NET Core 3.1 and .NET 5.

Top Solution Authors
Top Kudoed Authors