12
$\begingroup$

I have the following nested list

CombiningCyclesCase2={{1, 2, 3, 0, 0}, {1, 2, 4, 3, 0}, {1, 2, 4, 5, 3}, {3, 2, 1, 4, 0}, {3, 2, 1, 5, 4}, {3, 2, 4, 1, 5}, {3, 4, 1, 2, 5}, {3, 2, 4, 5, 1}, {3, 5, 4, 1, 2}}

I want to replace the zeroes in the sublists that have zeroes, by the corresponding position of the zeroes. For instance, in the sublist {1,2,3,0,0} I want to replace the 0's to have {1,2,3,4,5}, but in the sublists that don't have any zeros, I want to leave them like they are. I tried doing this with the following line of code, where n=5:

n = 5;
Table[If[Max[CombiningCyclesCase2[[i]]] == n, 
  CombiningCyclesCase2[[i]]], 
 ReplacePart[CombiningCyclesCase2[[i]], 
  Thread[Range[Max[CombiningCyclesCase2[[i]]] + 1, n]] -> 
   Range[Max[CombiningCyclesCase2[[i]]] + 1, n]], {i, 
  Length[CombiningCyclesCase2]}]

However, I get the error Part::pkspec1: The expression i cannot be used as a part specification. >>. Does anyone have a suggestion on how to solve this problem or if there is an easier way to do this?

$\endgroup$
1
  • $\begingroup$ Are you the same as cesar? If so, you can talk to the moderators to get your two accounts merged. $\endgroup$
    – march
    Commented Jun 27, 2016 at 3:38

8 Answers 8

8
$\begingroup$

One solution:

MapIndexed[If[# == 0, Last[#2], #] &, CombiningCyclesCase2, {2}]
$\endgroup$
7
$\begingroup$
ClearAll[f]
f = ReplacePart[#, # -> Last @# & /@ Position[#, 0]]&;

f @ CombiningCyclesCase2

Mathematica graphics

$\endgroup$
6
$\begingroup$

If your lists are large (and rectangular as your example), this s/b considerably faster than existing answers:

fix=With[{d=Dimensions@#},#+BitXor[1,Unitize@#]*ConstantArray[Range@d[[2]],d[[1]]]]&;

or simpler and similar speed:

fix2=With[{rx = Range@Length@#[[1]]}, (# + BitXor[1, Unitize[#]]*rx) & /@ #] &;
$\endgroup$
1
  • $\begingroup$ I'm so sorry.Seemed a bit repetitive to your answer.If necessary,I'll delete my answer. $\endgroup$
    – yode
    Commented Jun 26, 2016 at 8:33
4
$\begingroup$
fun:=(1-Unitize[#])*Range[Length@#]+#&

Usage

fun/@CombiningCyclesCase2

{{1,2,3,4,5},{1,2,4,3,5},{1,2,4,5,3},{3,2,1,4,5},{3,2,1,5,4},{3,2,4,1,5},{3,4,1,2,5},{3,2,4,5,1},{3,5,4,1,2}}

$\endgroup$
2
$\begingroup$
foo[x_] := ReplacePart[i_ :> If[x[[i]] == 0, i, x[[i]]]] @ x

foo /@ CombiningCyclesCase2

{{1, 2, 3, 4, 5}, {1, 2, 4, 3, 5}, {1, 2, 4, 5, 3}, {3, 2, 1, 4, 5}, {3, 2, 1, 5, 4}, {3, 2, 4, 1, 5}, {3, 4, 1, 2, 5}, {3, 2, 4, 5, 1}, {3, 5, 4, 1, 2}}

$\endgroup$
2
$\begingroup$

Another way to do this using Delete, Partition and Riffle:

f[l_] := Map[Apply[Join, #] &,
    Partition[
            Riffle[Function[Delete[#, Position[#, 0]]][l],
                Map[Function @ Complement[Range @ Last @ Dimensions @ #, #], l]
            ],
            {2}
        ]
   ];

Test:

f@CombiningCyclesCase2

(*{{1, 2, 3, 4, 5}, {1, 2, 4, 3, 5}, {1, 2, 4, 5, 3}, {3, 2, 1, 4, 5}, 
{3, 2, 1, 5, 4}, {3, 2, 4, 1, 5}, {3, 4, 1, 2, 5}, {3, 2, 4, 5, 1}, {3, 5, 4, 1, 2}}*)
$\endgroup$
1
  • 1
    $\begingroup$ You can think about removing the MatrixQ restriction. $\endgroup$
    – Syed
    Commented Sep 14, 2023 at 3:26
2
$\begingroup$
list = {
   {1, 2, 3, 0, 0}, {1, 2, 4, 3, 0}, {1, 2, 4, 5, 3}, 
   {3, 2, 1, 4, 0}, {3, 2, 1, 5, 4}, {3, 2, 4, 1, 5}, 
   {3, 4, 1, 2, 5}, {3, 2, 4, 5, 1}, {3, 5, 4, 1, 2}};

Using SubsetMap (new in 12.0)

f[x_] := With[{p = Flatten @ Position[x, 0]}, SubsetMap[p &, x, p]]

f /@ list

{{1, 2, 3, 4, 5}, {1, 2, 4, 3, 5}, {1, 2, 4, 5, 3}, {3, 2, 1, 4, 5}, {3, 2, 1, 5, 4}, {3, 2, 4, 1, 5}, {3, 4, 1, 2, 5}, {3, 2, 4, 5, 1}, {3, 5, 4, 1, 2}}

$\endgroup$
1
$\begingroup$

MapIndexed was designed to handle such problems. However, in the interest of computational diversity, let's use MapThread with PositionIndex. I have added a slightly longer sublist for testing and taken some liberty with output styles.

Clear["Global`*"];
CombiningCyclesCase2 = {{1, 2, 3, 0, 0}, {1, 2, 4, 3, 0}, {1, 2, 4, 5,
    3}, {3, 2, 1, 4, 0}, {3, 2, 1, 5, 4}, {3, 2, 4, 1, 5}, {3, 4, 1, 
   2, 5}, {0, 11, 0, 11, 0, 11, 0, 11}, {3, 2, 4, 5, 1}, {3, 5, 4, 1, 
   2}};

reps = PositionIndex[#][0] & /@ 
   CombiningCyclesCase2 /. {Missing[__] :> {}, 
   a_Integer :> a -> Style[a, Red]} 

MapThread[ReplacePart[#1, #2] &,  {CombiningCyclesCase2, reps}]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.