I need to select n elements from a list, which satisfy a condition. I need something like

Take[Select[r, (Length[FactorInteger[#]] > 100)&], 500]

but r might be something like Range[10^10], and I don't want Select to range over 10^10 elements when I need only first 500.

  • 1
    $\begingroup$ Cases has a number restriction: Cases[r, x_ /; Length[FactorInteger[x]] > 100, 1, 500]. But remember that if the length of Select[r, ...] is a problem, then surely the length of r itself must be an even bigger problem, right? $\endgroup$ – Marius Ladegård Meyer Aug 11 '17 at 10:54
  • 4
    $\begingroup$ Are you aware that Select has an optional final argument that specifies the max number of items to return, and early terminates when it reaches that limit? E.g. Select[Range[500],#<600&,200]===Range[200] $\mapsto$ True . Perhaps you're asking for a way to pass a lazy-evaluating list to a select type operation? $\endgroup$ – John Joseph M. Carrasco Aug 11 '17 at 11:14
  • $\begingroup$ Yes, "lazy-evaluating list" is that interests me. It's strange that I missed this moment in the Help. $\endgroup$ – 32seph Aug 11 '17 at 11:56
  • 2
    $\begingroup$ If you really want a lazy list w/ a filter, consider the beautiful functional approach by WReach here . $\endgroup$ – John Joseph M. Carrasco Aug 11 '17 at 13:16
func [r_, l_] := Module[{i = 0},

  Reap[Scan[If[Length@FactorInteger[#]  > 100 && i < l, Sow[#]; i = i + 1] &, r]][[2]]

| improve this answer | |
  • $\begingroup$ If enough results are accumulated fast enough, it might be faster to use a While loop. If it needs to go through the entire list, though, Scan is faster. All depends on how the elements you want are distributed. $\endgroup$ – aardvark2012 Aug 12 '17 at 4:12
  • $\begingroup$ @aardvark2012 thanks, I didn't know it $\endgroup$ – Alucard Aug 12 '17 at 9:13

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