Collect for nonlinear terms

Is there a way to expand Collect, so that it does not only separate equations by polynomial order, but by general nonlinear functions?

For example

expression = (2 + x + x^2 + x f[x] + x Sin[x]);
List@@Collect[expression, x]


results in {2, x^2, x (1 + f[x] + Sin[x])} instead of {2, x, x^2, x f[x], x Sin[x]}

My approach so far is to divide by the nonlinearity in question and check whether the denominator is one:

allTerms = List @@ expression
library =
DeleteDuplicates[
Times @@ # & /@ Tuples[{x^Range[0, 2], Times @@ # & /@ Subsets[{1, x f[x], x Sin[x]}][[2 ;;]]}]]
coeffs = Table[
Total@Select[allTerms/element, (Denominator[#] == 1 \[And] FreeQ[#, x]) &]
, {element, library}]


I have a feeling there must be a better approach to it.

One obvious flaw of the code is that it won't work when there are denominators in the original expression.

I saw in the documentation that Collect can be used to extract terms by derivative order D[f[Sqrt[x^2 + 1]], {x, 3}]; Collect[%, Derivative[_][f][_], Together]. However, I am not sure how to apply this to my situation.

Update:

Thanks both to Omrie and Nasser for their answers. Both asnwers work perfectly on my test data set given. Unfortunately I realized that my example was overly simplified (each nonlinear term only occurred once and there were no other variables).

Here is an example that more closely resembles my problem:

expression = (2 + y + x + x^2 + x f[x,y] + x^2 f[x,y] + x Sin[x] + x y f[x,y] + y x^2);
List @@ Collect[expression, x]


resulting in {2, y, x^2 (1 + y + f[x,y]), x (1 + f[x,y] + y f[x,y] + Sin[x])} instead of {2+y,x,x^2 (1 + y), x^2 f[x,y], (1 + y) x f[x,y], x Sin[x])}

If Collect does not work, maybe one could use Simplify with a suitable ComplexityFunction or ExcludedForms?

Without additional options Simplify oversimplies things: Simplify[expression] leads to 2 + x + x^2 + y + x^2 y + x (1 + x + y) f[x,y] + x Sin[x]

You can try this

expression = (2 + x + x^2 + x f[x] + x Sin[x]);
List @@ Collect[expression, _[x]]


which would yield the desired result

{2, x, x^2, x f[x], x Sin[x]}

• Could you please explain the meaning of _[x]? Apr 26, 2020 at 16:53
• _[x] is a pattern object that can stand for any expression followed by [x] Apr 27, 2020 at 11:29

This should cover most cases:

List @@
Collect[expression,
Select[#, ! FreeQ[#, x] &] & @
DeleteDuplicates @
MonomialList[expression] /. z_Times :> Select[z, !FreeQ[#, x] &]
]


There is also a more general function available here

• Could you elucidate on /. z_Times :> Select[z, ! FreeQ[#, x] &] please? Especially z_Times and :>. Leaving out Times or replacing :> by -> does not work anymore. Apr 26, 2020 at 17:56
• No. Please just read wolfram.com/language/elementary-introduction/2nd-ed/… and similar introductions. Apr 26, 2020 at 18:50