# Select certain terms in an expression

I would like to have a function to select terms containing q[i] terms in expressions, for example, for an expression

a q[i]+b +c q[j]+d


I would like the function to return

a q[i]+c q[j]


as result. Also at the same time, for a bare

q[i]


the same function would return

q[i]


How to realize such function? Thanks

expr = a q[i] + b + c q[j] + d;
f = DeleteCases[#, Except[_.  _q], If[Head[#] === q, 0, 1]] &
f @ expr


a q[i] + c q[j]

f @ q[i]


q[i]

Alternatively,

f2 = Select[#, Function[x, If[Head@# === q, True, Not @ FreeQ[x, _q]]]] &;
f2 @ expr


a q[i] + c q[j]

f2 @ q[i]


q[i]

• This realize the first requirement, but for the bare $q[i]$, it returns $q[]$ – XiaoaiX Jan 11 at 7:24
• @XiaoaiX, I will update if i find a fix. – kglr Jan 11 at 7:39
• thanks, from your answer, I also got confused about how the Select and Cases handle the List argument, see the question I just post here mathematica.stackexchange.com/questions/189270/… – XiaoaiX Jan 11 at 7:46

A pattern-based approach.

fn[x_. y_q + z_.] := x y + fn[z]
_fn = 0;

a q[i] + b + c q[j] + d // fn

q[i] // fn

a q[i] + c q[j]

q[i]