Skip to main content
added 894 characters in body
Source Link
Mr.Wizard
  • 273.1k
  • 34
  • 595
  • 1.4k

You wrote:

It's important not to use IF checking every element whether it satisfies provided condition.

I cannot agree with this, unless you mean that once the sought element is found the rest of the elements should not be checked (possibly) using If. What I mean is that even if not using If itself there is going to be some kind of by-element checking until the target value is found.

One approach to what I believe you want:

SeedRandom[0]
a = RandomInteger[9, 10]
{7, 0, 8, 2, 1, 5, 8, 0, 6, 7}
p = FirstPosition[a, 5][[1]]

Join[Take[a, p], ConstantArray[0, Length@a - p]]
{7, 0, 8, 2, 1, 5, 0, 0, 0, 0}

Or more concise but less efficient:

Join[Take[a, p], 0 Drop[a, p]]
{7, 0, 8, 2, 1, 5, 0, 0, 0, 0}

Update

Based on your comments I believe this should be of use to you:

cTable[f_, n_] := FoldList[If[# == 0, 0, f @ #2] &, f @ 1, 2 ~Range~ n]

Example:

f = Mod[2 # + 1, 9] &;

cTable[f, 10]
{3, 5, 7, 0, 0, 0, 0, 0, 0, 0}

Note that f is only called four times here, not once for each element in the output. As proof we can add a Pause to it:

f = (Pause[1]; Mod[2 # + 1, 9]) &;

cTable[f, 10] // AbsoluteTiming
{4.010006, {3, 5, 7, 0, 0, 0, 0, 0, 0, 0}}

Because FoldList auto-compiles (by default for lists 100 or longer) this method should be acceptably fast. For example a list with nearly 5,000,000 zeros takes only a fraction of a second on my machine:

cTable[Mod[2 # + 1, 9] &, 5000000]; // AbsoluteTiming
{0.360001, Null}

You wrote:

It's important not to use IF checking every element whether it satisfies provided condition.

I cannot agree with this, unless you mean that once the sought element is found the rest of the elements should not be checked (possibly) using If. What I mean is that even if not using If itself there is going to be some kind of by-element checking until the target value is found.

One approach to what I believe you want:

SeedRandom[0]
a = RandomInteger[9, 10]
{7, 0, 8, 2, 1, 5, 8, 0, 6, 7}
p = FirstPosition[a, 5][[1]]

Join[Take[a, p], ConstantArray[0, Length@a - p]]
{7, 0, 8, 2, 1, 5, 0, 0, 0, 0}

Or more concise but less efficient:

Join[Take[a, p], 0 Drop[a, p]]
{7, 0, 8, 2, 1, 5, 0, 0, 0, 0}

You wrote:

It's important not to use IF checking every element whether it satisfies provided condition.

I cannot agree with this, unless you mean that once the sought element is found the rest of the elements should not be checked (possibly) using If. What I mean is that even if not using If itself there is going to be some kind of by-element checking until the target value is found.

One approach to what I believe you want:

SeedRandom[0]
a = RandomInteger[9, 10]
{7, 0, 8, 2, 1, 5, 8, 0, 6, 7}
p = FirstPosition[a, 5][[1]]

Join[Take[a, p], ConstantArray[0, Length@a - p]]
{7, 0, 8, 2, 1, 5, 0, 0, 0, 0}

Or more concise but less efficient:

Join[Take[a, p], 0 Drop[a, p]]
{7, 0, 8, 2, 1, 5, 0, 0, 0, 0}

Update

Based on your comments I believe this should be of use to you:

cTable[f_, n_] := FoldList[If[# == 0, 0, f @ #2] &, f @ 1, 2 ~Range~ n]

Example:

f = Mod[2 # + 1, 9] &;

cTable[f, 10]
{3, 5, 7, 0, 0, 0, 0, 0, 0, 0}

Note that f is only called four times here, not once for each element in the output. As proof we can add a Pause to it:

f = (Pause[1]; Mod[2 # + 1, 9]) &;

cTable[f, 10] // AbsoluteTiming
{4.010006, {3, 5, 7, 0, 0, 0, 0, 0, 0, 0}}

Because FoldList auto-compiles (by default for lists 100 or longer) this method should be acceptably fast. For example a list with nearly 5,000,000 zeros takes only a fraction of a second on my machine:

cTable[Mod[2 # + 1, 9] &, 5000000]; // AbsoluteTiming
{0.360001, Null}
Source Link
Mr.Wizard
  • 273.1k
  • 34
  • 595
  • 1.4k

You wrote:

It's important not to use IF checking every element whether it satisfies provided condition.

I cannot agree with this, unless you mean that once the sought element is found the rest of the elements should not be checked (possibly) using If. What I mean is that even if not using If itself there is going to be some kind of by-element checking until the target value is found.

One approach to what I believe you want:

SeedRandom[0]
a = RandomInteger[9, 10]
{7, 0, 8, 2, 1, 5, 8, 0, 6, 7}
p = FirstPosition[a, 5][[1]]

Join[Take[a, p], ConstantArray[0, Length@a - p]]
{7, 0, 8, 2, 1, 5, 0, 0, 0, 0}

Or more concise but less efficient:

Join[Take[a, p], 0 Drop[a, p]]
{7, 0, 8, 2, 1, 5, 0, 0, 0, 0}