Forum Discussion

Dicken's avatar
Dicken
Post Prodigy
1 year ago
Solved

Insert different table row or list range at each positon

Hi, 

Any suggestion about this   i want to insert a  tablle row or list range at varous positons, but a different value at 
each position  ie 1st postion "A", 2nd "B" or whatever  so , starting with ; 

= let alist =  { "A".."Z"} in  
List.Accumulate( {3,7,12} , alist, (s,c)=>List.InsertRange( s, c, {null}  ) )

I have used nested accumulation one  inside the other   but have not got it to work on this, this is jsut an idea. 
I have thougt of using list generate rather than accumulate, and again have the insert but not the change of value to insert at the moment . 

Richard 

Richard. 

  • List.Generate versions if interested.

     

    This iterates the inserts and then grabs last one as output.

     

    let
        alist =  {"A".."Z"},
        addPosition = {3,7,12}, // buffer if query output
        addVals = {1,2,3}, // buffer if query output
        genAdds = List.Generate(
            ()=>[ i = 0, l = alist ],
            each [i] <= List.Count(addPosition),
            each let curIndex = [i] in [
                i = curIndex+1,
                l = List.InsertRange( [l], addPosition{curIndex}, {addVals{curIndex}} )
            ],
            each [l]
        ),
        output = List.Last( genAdds )
    in
        output

     

     

    And here is a variation where inserts retain original positioning.

     

    let
        alist =  {"A".."Z"},
        addPosition = {3,7,12}, // buffer if query output
        addVals = {1,2,3}, // buffer if query output
        addCount = List.Count(addPosition),
        genAdds = List.Generate(
            ()=>-1,
            each _ < addCount,
            each _ + 1,
            each [
                isLast = _+1 = addCount,
                curPos=if _ = -1 then 0 else addPosition{_}, 
                nextPos=if isLast then List.Count(alist) else addPosition{_+1}, 
                count = nextPos-curPos, 
                output = List.Range( alist, curPos, count ) & ( if isLast then {} else {addVals{_+1}} ) 
            ][output]
        ),
        combineParts = List.Combine( genAdds )
    in
        combineParts

     

     

5 Replies

  • Are you looking for something like this?

    let 
        alist = {"A".."Z"},
        list_to_insert = 
        {
            {"abc", "def", "ghi"},
            {"zyx", "wvu", "tsr"},        
            {123, 456,789},
            {987, 654, 321}
        },
        positions_list = {3, 7, 12, 7},
        zipped_list =  List.Zip({positions_list, List.Numbers(0, List.Count(positions_list))})
    in  
        List.Accumulate( zipped_list , alist, (s,c)=>List.InsertRange(s, c{0}, list_to_insert{c{1}}))

     

  • List.Generate versions if interested.

     

    This iterates the inserts and then grabs last one as output.

     

    let
        alist =  {"A".."Z"},
        addPosition = {3,7,12}, // buffer if query output
        addVals = {1,2,3}, // buffer if query output
        genAdds = List.Generate(
            ()=>[ i = 0, l = alist ],
            each [i] <= List.Count(addPosition),
            each let curIndex = [i] in [
                i = curIndex+1,
                l = List.InsertRange( [l], addPosition{curIndex}, {addVals{curIndex}} )
            ],
            each [l]
        ),
        output = List.Last( genAdds )
    in
        output

     

     

    And here is a variation where inserts retain original positioning.

     

    let
        alist =  {"A".."Z"},
        addPosition = {3,7,12}, // buffer if query output
        addVals = {1,2,3}, // buffer if query output
        addCount = List.Count(addPosition),
        genAdds = List.Generate(
            ()=>-1,
            each _ < addCount,
            each _ + 1,
            each [
                isLast = _+1 = addCount,
                curPos=if _ = -1 then 0 else addPosition{_}, 
                nextPos=if isLast then List.Count(alist) else addPosition{_+1}, 
                count = nextPos-curPos, 
                output = List.Range( alist, curPos, count ) & ( if isLast then {} else {addVals{_+1}} ) 
            ][output]
        ),
        combineParts = List.Combine( genAdds )
    in
        combineParts

     

     

  • Dicken's avatar
    Dicken
    Post Prodigy

    Thanks I'll have to work through  your method but i do like generate;  I did come up with tihis method, 

     let alist = {"A".."Z"} , pos = {7, 12, 16} , val ={"cat","dog","horse"} ,
    index = {0..List.Count(pos)-1 } 
    in List.Accumulate( index, alist, (s,c)=>   List.InsertRange( s, pos {c} , { val {c} } ) )

    Obviuosly you might want to subtract 1 from each postion, but it does work. 

  • Dicken's avatar
    Dicken
    Post Prodigy

    to answer my own and based on previous answere I have this , not sure it's very effecient but does work; 

    let
      Source =
        let
          alist = {"A" .. "Z"},
          pos   = {7, 12, 15},
          val   = {"100", "200", "300"}
        in
          List.Generate(
            () => [x = 0, y = pos{0}, z = alist, i = val{0}],
            each [x] < 4,
            each [x = [x] + 1, y = pos{x}, i = val{x}, z = List.InsertRange([z], [y], {[i]})],
            each [z]
          ),
      Custom1 = List.Last(Source)
    in
      Custom1