Jump to content

Most effective way to fill an array with 2 values?


End User

Recommended Posts

I'm looking for an effective/elegant way to fill an array with a specific set of 2 different values. For example, I'd like to create an array with 100 elements where 46 of the elements would have the value 'a' and the rest would have the value 'b' (so there would be 46 with 'a' and 54 with 'b'). I've had a couple of suggestions...one is to loop from 1 to 100 and count the first x elements, inserting 'a' until it hits 46, and then switch to inserting 'b' for the remainder. This works just fine, but seems slightly klunky. Another suggestion was to use array_fill() to fill an array with 100 'b' entries and then use a loop to fill 46 of them with 'a'. This also works just fine, but like the first method, seems a bit klunky. Another suggestion was to use array_fill() twice, once with 46 'a' entries, once with 54 'b' entries, and then use array_merge() to concatenate the arrays, ending up with one array with 100 elements properly filled. (The arrays have numeric keys, so they will append instead of overwriting each other.)I'm not sure if it makes any difference which way it's done, but I'd be interested to hear what people think is the "best" method (whatever "best" means- fastest, least memory, cleanest code, whatever). Or perhaps someone can come up with another method entirely that might be better.

Link to comment
Share on other sites

My vote:

Another suggestion was to use array_fill() twice, once with 46 'a' entries, once with 54 'b' entries, and then use array_merge() to concatenate the arrays, ending up with one array with 100 elements properly filled. (The arrays have numeric keys, so they will append instead of overwriting each other.)
You could also use the array_fill above, then the + operatorhttp://www.php.net/manual/en/language.operators.array.php
Link to comment
Share on other sites

Assuming you don't mind the use of "magic numbers":$arr = array_fill( 0, 46, "a");$arr += array_fill( 46, 54, "b");I'm pretty sure the second call to array_fill will generate a temporary array in memory, before the merge, but garbage collection should clean it up as soon as that memory is needed. This saves you the trouble of explicitly creating a placeholder array and then unsetting it when you no longer need it (assuming that's a priority for you).I don't recall benchmark tests that indicate whether + or array_merge is faster, but with only 100 elements, the difference should be negligible.

Link to comment
Share on other sites

$a + $b Union Union of $a and $b.
After further thought, you might want to create an array/value map, like so:$aValueMap=array('a'=>array('min'=>0,'max'=>45), 'b'=>array('min'=>46,'max'=>100));or$aValueMap=array(0=>'a',46=>'b') and to reference it ... you could either use array_search or loop through the array backwards until the index you're searching for is greater than the index you're comparing to.$cTarget='a';$iTarget=array_search($cTarget,$aValueMap); /* Using the first example to get the key of the value, and the range of associated values */$iTarget= /* Value that you are trying to find in the array - assuming some number between 0 and 99 */$iIndex=count($aValueMap); /* Using the second assignment example */while ( ($iIndex>=0) && ($iTarget<$aValueMap[$iIndex])) $iIndex--;
Link to comment
Share on other sites

$arr = array_fill( 0, 46, "a");$arr += array_fill( 46, 54, "b");
To expand on that, and the array_merge idea, I think this is probably the closest thing to a one liner you can get:
$arr = array_merge(array_fill(0, 46, "a"), array_fill(46, 54, "b"));

And if you don't like magic numbers, here's a more abstracted way of doing the same:

function array_fill_split($cutAt, $length, $beforeCutPoint, $afterCutPoint) {return array_merge(array_fill(0, $cutAt, $beforeCutPoint), array_fill($cutAt, $length - $cutAt, $afterCutPoint));}

And when you use it:

$arr = array_fill_split(46, 100, 'a', 'b');

Link to comment
Share on other sites

Thank you.

Assuming you don't mind the use of "magic numbers":$arr = array_fill( 0, 46, "a");$arr += array_fill( 46, 54, "b");
I tested and that works nicely. I substitute the actual numbers with vars so 'magic numbers' aren't a problem: $fillpoint = 100 - $win_chance;$rand_list = array_fill( 0, $win_chance, 'WIN');$rand_list += array_fill( $win_chance, $fillpoint , 'LOSE');Currently I'm using this:for($i=1; $i<=100; $i++){ if($i <= $win_chance){$rand_list[] = 'WIN';}else{$rand_list[] = 'LOSE';}}But, since the code will be run repeatedly, I'm going to do some testing and see if there's any real difference in speed or memory. I don't know if there's any real advantage to either method, but for very large arrays I'm sure one one would be faster/more efficient.
Link to comment
Share on other sites

My gut tells me that for large arrays or repeated iterations, the for-loop will be slowest, since it's interpreted, whereas array_fill is a compiled function. But only a test would let us know for sure.

Link to comment
Share on other sites

To expand on that, and the array_merge idea, I think this is probably the closest thing to a one liner you can get:
function array_fill_split($cutAt, $length, $beforeCutPoint, $afterCutPoint) {return array_merge(array_fill(0, $cutAt, $beforeCutPoint), array_fill($cutAt, $length - $cutAt, $afterCutPoint));}

Hmmm, this looks good, and I think this is what I'll end up using.
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...