Good Day!
I have array structure for 13 with range (1,13);
it something like
array(1,2,3,4,5,6,7,8,9,10,11,12,13);
$slice=2;
$ignore = 3;
i want array structure like array(3,4,5,8,9,10,13);
I tried with array_slice function but i couldn't offset the value sequentially
array_slice($array,2,13,true);
is there a way to ignore the next 3 values and add slice to the next second until last array, any native function or key will be great.
Thanks,
vicky
Using array_merge(), function one could join two array slice. This will return a new array.
http://php.net/manual/en/function.array-merge.php
<?php
$slice = 2;
$ignore = 3;
$a = array(1,2,3,4,5,6,7,8,9,10,11,12,13);
$a = array_merge(array_slice($a, $slice,$ignore),array_merge(array_slice($a, 2* $slice + $ignore,3), array_slice($a, 3* $slice + 2*$ignore)));
var_dump($a);
?>
I hope you got it. :)
Here's a function that will recursively perform an "asymmetric" slicing of an array of n length:
function slice_asym(array $head, $exclude, $include)
{
$keep = array_slice($head, $exclude, $include);
$tail = array_slice($head, $exclude + $include);
return $tail ? array_merge($keep, slice_asym($tail, $exclude, $include))
: $keep;
}
Recursion requires a base case where recursion stops and all scopes unwind and return. In our case, we want to stop when the tail contains no more elements.
array_slice() always returns an array - if there are no elements to return for its given offset, array_slice() returns an empty array. So, for each recursion, we want to:
Slice out the element(s) that we want to $keep
Create a $tail - this is a subset of the array that excludes the elements that we both want to ignore and keep in the current scope ($exclude + $include).
If the $tail is not empty, create a new level of recursion. Otherwise stop recursion and merge all current $keep elements with the result of the next level of recursion.
In pseudocode, this looks something like:
# step 1: first recursion
head = [1,2,3,4,5,6,7,8,9,10,11,12,13]
keep = [3,4,5]
tail = [6,7,8,9,10,11,12,13] # tail not empty
# step 2: second recursion
head = [6,7,8,9,10,11,12,13]
keep = [8,9,10]
tail = [11,12,13] # tail not empty
# step 3: third recursion
head = [11,12,13]
keep = [13]
tail = [] # tail empty: base case met!
# return and merge `keep` elements
[3,4,5] + [8, 9, 10] + [13] -> [3,4,5,8,9,10,13]
As per your example, the following invocation:
$range = range(1, 13); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
$sliced = slice_asym($range, 2, 3);
print_r($sliced);
Yields:
Array
(
[0] => 3
[1] => 4
[2] => 5
[3] => 8
[4] => 9
[5] => 10
[6] => 13
)
Edit
If you are using PHP version 5.5 or above, this is also a good use case for a generator.
These are useful because:
A generator allows you to write code that uses foreach to iterate over a set of data without needing to build an array in memory, which may cause you to exceed a memory limit, or require a considerable amount of processing time to generate.
So, you would not have to pre-create an array of sequential values:
Instead, you can write a generator function, which is the same as a normal function, except that instead of returning once, a generator can yield as many times as it needs to in order to provide the values to be iterated over.
We could implement a generator for your use case like so:
/**
*
* #param int $limit
* #param int $exclude
* #param int $include
* #return int
*/
function xrange_asym($limit, $exclude, $include) {
if ($limit < 0 || $exclude < 0 || $include < 0) {
throw new UnexpectedValueException(
'`xrange_asym` does not accept negative values');
}
$seq = 1;
$min = $exclude;
$max = $exclude + $include;
while ($seq <= $limit) {
if ($seq > $min && $seq <= $max) {
yield $seq;
}
if ($seq === $max) {
$min = $exclude + $max;
$max = $exclude + $include + $max;
}
$seq = $seq + 1;
}
}
and use it, like so:
foreach (xrange_asym(13, 2, 3) as $number) {
echo $number . ', '; // 3, 4, 5, 8, 9, 10, 13
}
Or use iterator_to_array() to generate the whole range as an array:
print_r(iterator_to_array(xrange_asym(13, 2, 3)));
Hope this helps :)
Related
What I try to achieve: randomize the order of all elements in an array, but allow each element to change its position only by a limited number of "steps".
Say I have an array like below, and I wish to randomize with a limit of 2 steps:
$array = [92,12,2,18,17,88,56];
An outcome could be: [2,12,92,17,18,56,88] (all elements of the array moved a maximum of 2 steps), but it could not be: [56,92,2,12,17,18,88] because in this example 56 moved too far.
I considered using a combination of array_chunk and shuffle, but this is problematic because elements will be shuffled inside their chunk, resulting in elements at the beginning or end of a chunk only moving in one direction. This is what I came up with (and problematic):
// in chunks of 3 an element can move a max. of 2 steps.
$chunks = array_chunk($array, 3);
$newChunks = [];
foreach ($chunks as $chunk){
$keys = array_keys($chunk);
shuffle($keys);
$newChunk = [];
foreach ($keys as $key){
$newChunk[$key] = $chunk[$key];
}
$newChunks[] = $newChunk;
}
Another idea I had was to get the key of the item in the array and with rand add of subtract my limit. For example:
foreach ( $array as $key => $value ) {
$newArray[] = ["key" => $key+rand(-2,2), "value" => $value];
};
This creates a new array with each of its elements being an array with the original value plus a value key that is the original key plus or minus 2. I could flatten this array, but the problem with this is that I can have duplicate keys.
I created this function to do this, but I guess it needs more improvements:
/**
* #param array $array
* #param int $limit
* #return array
*/
function shuffleArray(array $array, int $limit): array
{
$arrayCount = count($array);
$limit = min($arrayCount, $limit);
for ($i = 0; $i < $limit; $i++) {
for ($j = 0; $j < $arrayCount;) {
$toIndex = min($arrayCount - 1, $j + rand(0, 1));
[$array[$j], $array[$toIndex]] = [$array[$toIndex], $array[$j]];
$j += (($toIndex === $j) ? 1 : 2);
}
}
return $array;
}
Test:
$array = [92, 12, 2, 18, 17, 88, 56];
$limit = 2;
$result = shuffleArray($array, $limit); // [12, 92, 17, 2, 18, 56, 88]
Here is a possible solution in one pass :
Try to swap each element at position i with an element between i (stay in place) and i+x. I look only forward to avoid swaping an element several times. And I need an extra array to flag the already swapped elements. I don't need to process them in the future as they were already moved.
function shuffle_array($a, $limit)
{
$result = $a ;
$shuffled_index = array() ; // list of already shuffled elements
$n = count($result);
for($i = 0 ; $i < $n ; ++$i)
{
if( in_array($i, $shuffled_index) ) continue ; // already shuffled, go to the next elements
$possibleIndex = array_diff( range($i, min($i + $limit, $n-1)), $shuffled_index) ; // get all the possible "jumps", minus the already- shuffled index
$selectedIndex = $possibleIndex[ array_rand($possibleIndex) ]; // randomly choose one of the possible index
// swap the two elements
$tmp = $result[$i] ;
$result[$i] = $result[$selectedIndex] ;
$result[$selectedIndex] = $tmp ;
// element at position $selectedIndex is already shuffled, it needs no more processing
$shuffled_index[] = $selectedIndex ;
}
return $result ;
}
$array = [92,12,2,18,17,88,56];
$limit = 2 ;
shuffle_array($array, $limit); // [2, 18, 92, 12, 17, 56, 88]
I expect more elements to stay in place than in the solution of Kerkouch, as some elements can have very few remaining free choices.
I'm using the following code to retrieve the highest 3 numbers from an array.
$a = array(1,2,5,10,15,20,10,15);
arsort($a, SORT_NUMERIC);
$highest = array_slice($a, 0, 3);
This code correctly gives me the highest three numbers array(20,15,10); however, I'm interested in getting the highest 3 numbers including the ones that are identical. In this example, I'm expecting to get an array like array(10, 10, 15, 15, 20)
Might be simpler but my brain is tired. Use arsort() to get the highest first, count the values to get unique keys with their count and slice the first 3 (make sure to pass true to preserve keys):
arsort($a, SORT_NUMERIC);
$counts = array_slice(array_count_values($a), 0, 3, true);
Then loop those 3 and fill an array with the number value the number of times it was counted and merge with the previous result:
$highest = array();
foreach($counts as $value => $count) {
$highest = array_merge($highest, array_fill(0, $count, $value));
}
You can use a function like this:
$a = array(1,2,5,10,15,20,10,15); //-- Original Array
function get3highest($a){
$h = array(); //-- highest
if(count($a) >= 3){ //-- Checking length
$c = 0; //-- Counter
while ($c < 3 || in_array($a[count($a)-1],$h) ){ //-- 3 elements or repeated value
$max = array_pop($a);
if(!in_array($max,$h)){
++$c;
}
$h[] = $max;
}
sort($h); //-- sorting
}
return $h; //-- values
}
print_r(get3Highest($a));
Of course you can improve this function to accept a dinamic value of "highest" values.
The below function may be usefull
$a = array(1,2,5,10,15,20,10,15);
function getMaxValue($array,$n){
$max_array = array(); // array to store all the max values
for($i=0;$i<$n;$i++){ // loop to get number of highest values
$keys = array_keys($array,max($array)); // get keys
if(is_array($keys)){ // if keys is array
foreach($keys as $v){ // loop array
$max_array[]=$array[$v]; // set values to max_array
unset($array[$v]); // unset the keys to get next max value
}
}else{ // if not array
$max_array[]=$array[$keys]; // set values to max_array
unset($array[$keys]); // unset the keys to get next max value
}
}
return $max_array;
}
$g = getMaxValue($a,3);
Out Put:
Array
(
[0] => 20
[1] => 15
[2] => 15
[3] => 10
[4] => 10
)
You can modify it to add conditions.
I thought of a couple of other possibilities.
First one:
Find the lowest of the top three values
$min = array_slice(array_unique($a, SORT_NUMERIC), -3)[0];
Filter out any lower values
$top3 = array_filter($a, function($x) use ($min) { return $x >= $min; });
Sort the result
sort($top3);
Advantages: less code
Disadvantages: less inefficient (sorts, iterates the entire array, sorts the result)
Second one:
Sort the array in reverse order
rsort($a);
Iterate the array, appending items to your result array until you've appended three distinct items.
$n = 0;
$prev = null;
$top = [];
foreach ($a as $x) {
if ($x != $prev) $n++;
if ($n > 3) break;
$top[] = $x;
$prev = $x;
}
Advantages: more efficient (sorts only once, iterates only as much as necessary)
Disadvantages: more code
This gives the results in descending order. You can optionally use array_unshift($top, $x) instead of $top[] = $x; to get it in ascending order, but I think I've read that array_unshift is less efficient because it reindexes the array after each addition, so if optimization is important it would probably be better to just use $top[] = $x; and then iterate the result in reverse order.
I have arrays:
$arr1 = array(5, 3, 9, 11, 6, 15);
$arr2 = array(11, 20, 1, 3, 8);
Now I need to loop through $arr1 and find the largest number that is less than X:
foreach($arr1 as $x) {
//need element that is MAX in $arr2 but is less than $x
}
so for example for the first run when $x = 5, maximum in $arr2 is 3 that is less than 5.
Is it possible to do this without having nested loop? I do not want to loop through $arr2. I tried using array_filter but didnt really work. Maybe I used it wrong.
This is what I tried with array_filter:
$results = array();
foreach($arr1 as $x) {
$max = max(array_filter($arr2, function ($x) { return $x < $y; }));
$results[$x] = $max;
}
The result should be this:
5 => 3,
3 => 1,
9 => 8,
11 => 8,
6 => 3,
15 => 11
The problem is with the use of the lambda - PHP does not automatically capture variables in the enclosing scope. (The official Anonymous Functions is a bit sparse on the topic, so see In PHP 5.3.0, what is the function "use" identifier? as well.)
Compare the original, which returns an empty array as it is effectively $x < undefined
$arr2 = array(11, 20, 1, 3, 8);
$y = 5;
var_dump(array_filter($arr2, function ($x) { return $x < $y; }));
with the following that employs the use syntax to bind the variable in the function
$arr2 = array(11, 20, 1, 3, 8);
$y = 5;
var_dump(array_filter($arr2, function ($x) use ($y) { return $x < $y; }));
(Also, in the original code there was no $y variable at all, whoops!)
Here's a method that uses array_map() to return the values that are lower than your maximum variable, then uses max() to return the highest (as in your example).
In this example I've used $var as a variable by reference (the &), so that it can be used by the get_highest() callback function which is accessing it as a global variable.
function get_highest($x) {
global $var;
return $x < $var ? $x : 0;
}
$results = array();
foreach($arr1 as &$var) {
$results[$var] = max(array_map('get_highest', $arr2));
}
Without using global variables
You can modify this if you don't want to use global variables by passing in an array of parameters to array_map(). It's a little strange the way it works, because the parameter array needs to be the same length as the original array, so I've used array_fill() to fill it up to the required length with the current value, so the callback function can use it to compare:
function get_highest($x, $y) {
return $x < $y ? $x : 0;
}
$results = array();
foreach($arr1 as $var) {
$max = array_fill(0, count($arr2), $var);
$results[$var] = max(array_map('get_highest', $arr2, $max));
}
Any solution that reuses/resets arr2 will be of quadratic complexity, meaning that if you have an arr1 of size N and an arr2 of size M, you'll be doing around N*M operations.
Plus function calls and parameter passing in case of lambda functions.
A better strategy if N and M are very large is to sort both arrays (complexity is N log N + M log M), then use the same strategy as merge sort to loop through the arrays, saving their state. This will execute in at most N+M operations instead of N*M, making the overall complexity linearithmic.
The lambda solution is easier to understand, more robust and simpler to maintain, so unless there's a pressing reason (N and M in the tens of thousands), it is to be preferred. You are trading speed for ease of maintenance; but it is normally a sweet deal.
First you sort both arrays with PHP's array sort functions, and get
$arr1 = array(3, 5, 6, 9, 11, 15);
$arr2 = array(1, 3, 8, 11, 20);
$map = array();
$n = count($arr1);
$m = count($arr2);
for ($i = 0, $j = 0, $y = false; $i < $n;) {
if ($j == $m) {
$map[$arr1[$i++]] = $y;
} else {
if ($arr1[$i] <= $arr2[$j]) {
$map[$arr1[$i++]] = $y;
} else {
$y = $arr2[$j++];
}
}
}
I'm looking for a function that I can pass an array and a seed to in PHP and get back a "randomized" array. If I passed the same array and same seed again, I would get the same output.
I've tried this code
//sample array
$test = array(1,2,3,4,5,6);
//show the array
print_r($test);
//seed the random number generator
mt_srand('123');
//generate a random number based on that
echo mt_rand();
echo "\n";
//shuffle the array
shuffle($test);
//show the results
print_r($test);
But it does not seem to work. Any thoughts on the best way to do this?
This question dances around the issue but it's old and nobody has provided an actual answer on how to do it: Can i randomize an array by providing a seed and get the same order? - "Yes" - but how?
Update
The answers so far work with PHP 5.1 and 5.3, but not 5.2. Just so happens the machine I want to run this on is using 5.2.
Can anyone give an example without using mt_rand? It is "broken" in php 5.2 because it will not give the same sequence of random numbers based off the same seed. See the php mt_rand page and the bug tracker to learn about this issue.
Sorry, but accordingly to the
documentation the
shuffle function is seeded automatically.
Normally, you shouldn't try to come up with your own algorithms to randomize things since they are very likely to be biased. The Fisher-Yates algorithm is known to be both efficient and unbiased though:
function fisherYatesShuffle(&$items, $seed)
{
#mt_srand($seed);
for ($i = count($items) - 1; $i > 0; $i--)
{
$j = #mt_rand(0, $i);
$tmp = $items[$i];
$items[$i] = $items[$j];
$items[$j] = $tmp;
}
}
Example (PHP 5.5.9):
php > $original = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
php > $shuffled = (array)$original;
php > fisherYatesShuffle($shuffled, 0);
php > print_r($shuffled);
Array
(
[0] => 6
[1] => 0
[2] => 7
[3] => 2
[4] => 9
[5] => 3
[6] => 1
[7] => 8
[8] => 5
[9] => 4
)
php > $shuffled = (array)$original;
php > fisherYatesShuffle($shuffled, 0);
php > print_r($shuffled);
Array
(
[0] => 6
[1] => 0
[2] => 7
[3] => 2
[4] => 9
[5] => 3
[6] => 1
[7] => 8
[8] => 5
[9] => 4
)
You can use array_multisort to order the array values by a second array of mt_rand values:
$arr = array(1,2,3,4,5,6);
mt_srand('123');
$order = array_map(create_function('$val', 'return mt_rand();'), range(1, count($arr)));
array_multisort($order, $arr);
var_dump($arr);
Here $order is an array of mt_rand values of the same length as $arr. array_multisort sorts the values of $order and orders the elements of $arr according to the order of the values of $order.
The problem you have is that PHP comes with two random number generators built in.
The shuffle() command does not use the mt_rand() random number generator; it uses the older rand() random number generator.
Therefore, if you want shuffle() to use a seeded number sequence, you need to seed the older randomiser, using srand() rather than mt_srand().
In most other cases, you should use mt_rand() rather than rand(), since it is a better random number generator.
The main question involves two parts. One is about how to shuffle. The other is about how to add randomness to it.
A simple solution
This is probably the simplest answer to the main question. It is sufficient for most cases in PHP scripting. But not all (see below).
function /*array*/ seedShuffle(/*one dimentional array*/ $array, /*integer*/ $seed) {
$tmp = array();
for ($rest = $count = count($array);$count>0;$count--) {
$seed %= $count;
$t = array_splice($array,$seed,1);
$tmp[] = $t[0];
$seed = $seed*$seed + $rest;
}
return $tmp;
}
The above method will do, even though it doesn't produce true random shuffles for all possible seed-array combinations. However, if you really want it to be balanced and all, I guess PHP shuldn't be your choice.
A more useful solution for advanced programmers
As stated by André Laszlo, randomization is a tricky business. It is usually best to let a dedicated object handle it. My point is, that you shouldn't need to bother with the randomness when you write the shuffle function. Depending on what degree of ramdomness you would like in your shuffle, you may have a number of PseudoRandom objects to choose from. Thus the above could look like this:
abstract class PseudoRandom {
protected abstract function /*integer*/ nextInt();
public function /*integer*/ randInt(/*integer*/ $limit) {
return $this->nextInt()%$limit;
}
}
function /*array*/ seedShuffle($array, /*PseudoRandom Object*/ $rnd) {
$tmp = array();
$count = count($array);
while($count>0) {
$t = array_splice($array,$rnd->randInt($count--),1);
$tmp[] = $t[0];
}
return $tmp;
}
Now, this solution is the one I would vote for. It separates shuffle codes from randomization codes. Depending on what kind of random you need you can subclass PseudoRandom, add the needed methods and your preferred formulas.
And, as the same shuffle function may be used with many random algorithms, one random algorithm may be used in different places.
In recent PHP versions, seeding the PHP builtin rand() and mt_rand() functions will not give you the same results everytime. The reason for this is not clear to me (why would you want to seed the function anyway if the result is different every time.) Anyway, it seems like the only solution is to write your own random function
class Random {
// random seed
private static $RSeed = 0;
// set seed
public static function seed($s = 0) {
self::$RSeed = abs(intval($s)) % 9999999 + 1;
self::num();
}
// generate random number
public static function num($min = 0, $max = 9999999) {
if (self::$RSeed == 0) self::seed(mt_rand());
self::$RSeed = (self::$RSeed * 125) % 2796203;
return self::$RSeed % ($max - $min + 1) + $min;
}
}
Usage:
// set seed
Random::seed(42);
// echo 10 numbers between 1 and 100
for ($i = 0; $i < 10; $i++) {
echo Random::num(1, 100) . '<br />';
}
The code above will output the folowing sequence every time you run it:
76
86
14
79
73
2
87
43
62
7
Just change the seed to get a completely different "random" sequence
A variant that also works with PHP version 7.2, because the php function create_function is deprecated in the newest php version.
mt_srand($seed);
$getMTRand = function () {
return mt_rand();
};
$order = array_map($getMTRand, range(1, count($array)));
array_multisort($order, $array);
return $array;
I guess this will do the job :
function choose_X_random_items($original_array , $number_of_items_wanted = -1 , $seed = FALSE ){
//save the keys
foreach ($original_array as $key => $value) {
$original_array[$key]['key_memory'] = $key;
}
$original_array = array_values($original_array);
$results = array();
if($seed !== FALSE){srand($seed);}
$main_random = rand();
$random = substr($main_random,0,( $number_of_items_wanted == -1 ? count($original_array) : min($number_of_items_wanted,count($original_array)) ));
$random = str_split($random);
foreach ($random AS $id => $value){
$pick = ($value*$main_random) % count($original_array);
$smaller_array[] = $original_array[$pick];
unset($original_array[$pick]);
$original_array = array_values($original_array);
}
//retrieve the keys
foreach ($smaller_array as $key => $value) {
$smaller_array[$value['key_memory']] = $value;
unset($smaller_array[$value['key_memory']]['key_memory']);
unset($smaller_array[$key]);
}
return $smaller_array;
}
In order to not limit the resulting array, set $number_of_items_wanted to -1
In order to not use a seed, set $seed to FALSE
Seeded shuffle while maintaining the key index:
function seeded_shuffle(array &$items, $seed = false) {
mt_srand($seed ? $seed : time());
$keys = array_keys($items);
$items = array_values($items);
for ($i = count($items) - 1; $i > 0; $i--) {
$j = mt_rand(0, $i);
list($items[$i], $items[$j]) = array($items[$j], $items[$i]);
list($keys[$i], $keys[$j]) = array($keys[$j], $keys[$i]);
}
$items = array_combine($keys, $items);
}
A simple solution:
$pool = [1, 2, 3, 4, 5, 6];
$seed = 'foo';
$randomIndex = crc32($seed) % count($pool);
$randomElement = $pool[$randomIndex];
It might not be quite as random as the Fisher Yates shuffle, but I found it gave me more than enough entropy for what I needed it for.
Based on #Gumbo, #Spudley, #AndreyP answers, it works like that:
$arr = array(1,2,3,4,5,6);
srand(123); //srand(124);
$order = array_map(function($val) {return rand();}, range(1, count($arr)));
array_multisort($order, $arr);
var_dump($arr);
Home Made function, using crc32(note:also returns negative value(https://www.php.net/manual/en/function.crc32.php))
$sortArrFromSeed = function($arr, $seed){
$arrLen = count($arr);
$newArr = [];
$hash = crc32($seed); // returns hash (0-9 numbers)
$hash = strval($hash);
while(strlen($hash) < $arrLen){
$hash .= $hash;
}
for ($i=0; $i<$arrLen; $i++) {
$index = (int) $hash[$i] * (count($arr)/9); // because 0-9 range
$index = (int) $index; // remove decimal
if($index !== 0) $index--;
array_push($newArr, $arr[$index]);
unset($arr[$index]);
$arr = array_values($arr);
}
return $newArr;
};
// TESTING
$arr = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
$arr = $sortArrFromSeed($arr,'myseed123');
echo '<pre>'.print_r($arr,true).'</pre>';
This seems the easiest for me...
srand(123);
usort($array,function($a,$b){return rand(-1,1);});
I want to replace all array values with 0 except work and home.
Input:
$array = ['work', 'homework', 'home', 'sky', 'door']
My coding attempt:
$a = str_replace("work", "0", $array);
Expected output:
['work', 0, 'home', 0, 0]
Also my input data is coming from a user submission and the amount of array elements may be very large.
A bit more elegant and shorter solution.
$aArray = array('work','home','sky','door');
foreach($aArray as &$sValue)
{
if ( $sValue!='work' && $sValue!='home' ) $sValue=0;
}
The & operator is a pointer to the particular original string in the array. (instead of a copy of that string)
You can that way assign a new value to the string in the array. The only thing you may not do is anything that may disturb the order in the array, like unset() or key manipulation.
The resulting array of the example above will be
$aArray = array('work','home', 0, 0)
A loop will perform a series of actions many times. So, for each element in your array, you would check if it is equal to the one you want to change and if it is, change it. Also be sure to put quote marks around your strings
//Setup the array of string
$asting = array('work','home','sky','door')
/**
Loop over the array of strings with a counter $i,
Continue doing this until it hits the last element in the array
which will be at count($asting)
*/
for($i = 0; $i < count($asting);$i++){
//Check if the value at the 'ith' element in the array is the one you want to change
//if it is, set the ith element to 0
if ($asting[$i] == 'work' || $asting[$i] == 'home')
$asting[$i] = 0;
}
Here is some suggested reading:
http://www.php.net/manual/en/language.types.array.php
http://www.php.net/manual/en/language.control-structures.php
But if you are struggling on stuff such as looping, you may want to read some introductory programming material. Which should help you really understand what's going on.
A bit other and much quicker way, but true, need a loop:
//Setup the array of string
$asting = array('bar', 'market', 'work', 'home', 'sky', 'door');
//Setup the array of replacings
$replace = array('home', 'work');
//Loop them through str_replace() replacing with 0 or any other value...
foreach ($replace as $val) $asting = str_replace($val, 0, $asting);
//See what results brings:
print_r ($asting);
Will output:
Array
(
[0] => bar
[1] => market
[2] => 0
[3] => 0
[4] => sky
[5] => door
)
An alternative using array_map:
$original = array('work','home','sky','door');
$mapped = array_map(function($i){
$exclude = array('work','home');
return in_array($i, $exclude) ? 0 : $i;
}, $original);
you may try array_walk function:
function zeros(&$value)
{
if ($value != 'home' && $value != 'work'){$value = 0;}
}
$asting = array('work','home','sky','door','march');
array_walk($asting, 'zeros');
print_r($asting);
You can also give array as a parameter 1 and 2 on str_replace...
Just a small point to the for loop. Many dont realize the second comparing task is done every new iteration. So if it was a case of big array or calculation you could optimize loop a bit by doing:
for ($i = 0, $c = count($asting); $i < $c; $i++) {...}
You may also want to see http://php.net/manual/en/function.array-replace.php for original problem unless the code really is final :)
Try This
$your_array = array('work','home','sky','door');
$rep = array('home', 'work');
foreach($rep as $key=>$val){
$key = array_search($val, $your_array);
$your_array[$key] = 0;
}
print_r($your_array);
There are a few techniques on this page that make zero iterated function calls -- which is good performance-wise. For best maintainability, I recommend separating your list of targeted string as a lookup array. By modifying the original array values by reference, you can swiftly replace whole strings and null coalesce non-targeted values to 0.
Code: (Demo)
$array = ['work', 'homework', 'home', 'sky', 'door'];
$keep = ['work', 'home'];
$lookup = array_combine($keep, $keep);
foreach ($array as &$v) {
$v = $lookup[$v] ?? 0;
}
var_export($array);
Output:
array (
0 => 'work',
1 => 0,
2 => 'home',
3 => 0,
4 => 0,
)
You can very easily, cleanly extend your list of targeted strings by merely extending $keep.
If you don't want a classic loop, you can use the same technique without modifying the original array. (Demo)
var_export(
array_map(fn($v) => $lookup[$v] ?? 0, $array)
);
this my final code
//Setup the array of string
$asting = array('work','home','sky','door','march');
/**
Loop over the array of strings with a counter $i,
Continue doing this until it hits the last element in the array
which will be at count($asting)
*/
for($i = 0; $i < count($asting); $i++) {
//Check if the value at the 'ith' element in the array is the one you want to change
//if it is, set the ith element to 0
if ($asting[$i] == 'work') {
$asting[$i] = 20;
} elseif($asting[$i] == 'home'){
$asting[$i] = 30;
}else{
$asting[$i] = 0;
}
echo $asting[$i]."<br><br>";
$total += $asting[$i];
}
echo $total;