Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a simple functional programming question: I have a simple EdgeList defined in Mathematica, I would like to modify the value of certain element of the list based on a condition. I see how to define the conditional If, but I don't know how to "scan" my EdgeList and modify the elements so that it returns another EdgeList. Could someone show me a simple example on how to accomplish this in Mathematica?

share|improve this question
    
You could try some Rule-based approach {a \[UndirectedEdge] b, b \[UndirectedEdge] c, c \[UndirectedEdge] a} /. a \[UndirectedEdge] x_ :> a \[UndirectedEdge] y –  ssch Dec 30 '12 at 12:43
    
@ssch Thanks for the input, however I cannot use a rule-based approach because I need to call a function behind the rules. And, as far as I know, when you apply the rule it will only call the function once for every edges matching the rule. In fact, what I want to do is to rename some edge: every edge with name "ABC" will become "ABC 1", "ABC 2", ... –  afentis Dec 30 '12 at 12:48

1 Answer 1

up vote 3 down vote accepted

First a list of UndirectedEdge

list = MapIndexed[UndirectedEdge[First[#2], #1] &, CharacterRange["a", "e"]]

Let's say you want to change all edges where the head is OddQ then you could do something like

list /. e : UndirectedEdge[a_, b_] :> If[OddQ[a], UndirectedEdge[a, b <> "1"], e]

The trick is to apply the rule to all edges but only change those which match your If condition. Maybe a bit clear is to use Map and first define a function which modifies exactly one UndirectedEdge

f[e : UndirectedEdge[a_, b_]] :=  If[OddQ[a], UndirectedEdge[a, b <> "1"], e]
f /@ list

There are many more ways and the more experienced users will probably use such a map with a pure Function where you don't have to define f separately.

Update for increasing numbers

To Map a function usually modifies every element of a list but the function itself only works on the data without knowing how many elements it has processed or other global things. To stick with Map we have to introduce some (at least locally defined) global variable which counts. I will use i here which is increased every time a the edge was modified. Additionally, I define the Function for modifying an edge in-place with Function and e is the edge-parameter:

Block[{i = 1},
 Function[e, 
   If[OddQ[First[e]], UndirectedEdge[First[e], Last[e] <> ToString[i++]], e]] /@ list
 ]
share|improve this answer
    
Looks great, thanks a lot :) if I may, just a little "side question", I see that in your example you append "1" to the edge value, how would you attempt to rewrite f so that it increments the number every time it's called? (a1, a2, ...) this is a problem I am facing at the moment... –  afentis Dec 30 '12 at 13:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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