Fill a list with 0's when fault the corresponding integer

Given a list of pairs where the first element of the pair is real values and the second element is an integer, how to obtain a new list of a length n ordered by the second elements being the first element If there is a gap in the ordered integers.

Better using an example:

Initial list:

{{b1,1},  {b3, 4},  {b4, 7}}

Apply a rule to obtain a list of length 10:

Final list:

{{b1,1},{0, 2}, {b2, 3}, {b3, 4},  {0, 5}, {0, 6}, {b4, 7}, {0, 8},{0,9}, {0, 10}}

I have a twisty solution.

list={{b1,1},{b3,4},{b4,7}}

Sort[DeleteDuplicatesBy[Join[list, Transpose[{PadLeft[{0},Last[Last[list]]+1],
Range[0,Last[Last[list]]]}]], Last],#1[[2]]<#2[[2]]&]

Thank you a lot.

Hi Guillermo,

The “twisty solution” generates this output

{{0, 0}, {b1, 1}, {0, 2}, {0, 3}, {b3, 4}, {0, 5}, {0, 6}, {b4, 7}}

which is different from the desired output. Which one is correct?

My solution is correct, but I think that my code could be improved considerably.

As Rohit pointed out the “twisty solution” is different from your final list given above. And it has not 10 elements. And what do you mean by

but I think that my code could be improved considerably.

? What about this? Is this “improved” ?

n = 10;
pairs = {{b1, 1}, {b3, 4}, {b4, 7}}
miss = Complement[Range[0, n], #[[2]] & /@ pairs];
inserts = {0, #} & /@ miss;
res = Sort[Flatten[Join[{pairs, inserts}], 1], #1[[2]] < #2[[2]] &]

This solution is slightly better. I thought that perhaps there would be a function (ArrayPad?) to implement my function almost immediately

Thank you

Just one more approach (using list = {{b1, 1}, {b3, 4}, {b4, 7}};):

list1 = Table[{0, n}, {n, 0, list[[-1, -1]]}];
Set[list1[[#2 + 1, 1]], #1] & @@@ list;

list1 is then the final result.

@Henrik: very cool, but the list doesn’t go up to 10.

and again another method (but I doubt that it is an improvement):

n = 10;
pairs = {{b1, 1}, {b3, 4}, {b4, 7}}
res =
 Flatten[Join[{
    Table[{0, j}, {j, 0, Min[Transpose[pairs][[2]]] - 1}],
    Flatten[
      Function[{x, y}, 
        Flatten[Join[{{x}, 
           Table[{0, j}, {j, x[[2]] + 1, y[[2]] - 1}], {y}}], 1]] @@@ 
       Partition[pairs, 2, 1], 1] // DeleteDuplicates,
    Table[{0, j}, {j, Max[Transpose[pairs][[2]]] + 1, n}]}], 1]

and of course introducing

list = Join[list, {{0, n}}]

with n = 10 resolves this issue

Hi Hans!

… but the list doesn’t go up to 10.

It is not clear to me how many entries the resulting list is supposed to have, but anyway:

list1 = Table[{0, n}, {n, 0, 10}];
Set[list1[[#2 + 1, 1]], #1] & @@@ list;

Another way

<| AssociationMap[{0, #} &, Range[0, 10]], AssociationThread[list[[All, 2]] -> list]|> // Values

(*
{{0, 0}, {b1, 1}, {0, 2}, {0, 3}, {b3, 4}, {0, 5}, {0, 6}, {b4, 7}, {0, 8}, {0, 9}, {0, 10}}
*)

Thank you all.

My preferred solution is

fun[list_,n_]:=<|AssociationMap[{0,#}&,Range[0,n]],AssociationThread[list[[All,2]]->list]|>//Values

But in fact you don’t need the Association-construct. Anyway, Rohits solution is cool

({0, #} & /@ Range[0, 10]) /. ({0, #[[2]]} -> # & /@ list)