Reference original array and double numbers PHP - php

I am getting deeper into PHP and I am attempting to double the original values of a given array in PHP. Here is the code if it were to return a different array:
$blandArray = array(1, 2, 3, 4);
function doubleNumbers($arr) {
$doubledArray = array();
for ($i=0; $i < count($arr); $i++) {
$doubledArray[$i] = $arr[$i] * 2;
}
return $doubledArray;
}
print_r(doubleNumbers($blandArray));
This returns the numbers doubled as expected, but in a new array. What I want is to double the original array. So, if blandArray was passed and echoed after running through the function, it would have the values doubled. I understand that I have to use the & to reference that in the argument passed, but I am having no luck. Any thoughts?

You have to not only pass by reference, but also change the variable!
function doubleNumbers(&$arr) {
for ($i=0; $i < count($arr); $i++) {
$arr[$i] *= 2;
}
}
$blandArray = array(1, 2, 3, 4);
doubleNumbers($blandArray);
print_r($blandArray);
Notice also that it doesn't return any more; that would also copy the array, so we just use it out-of-line.

As already mentioned, you pass by reference. This could also be achieved with array_map, such as:
$blandArray = array_map(function($val) {
return $val * 2;
}, $blandArray);

As far as im aware you would beable to just overwrite the old values . . .
$blandArray = array(1, 2, 3, 4);
function doubleNumbers($arr) {
for ($i=0; $i < count($arr); $i++) {
$arr[i] = $arr[i] * 2;
//or
$arr[i] *= 2;
}
}
print_r(doubleNumbers($blandArray));
I dont think you would have to return anything either if your always doubling the array into the same array you give the function. Im giving this answer from knowledge of Actionscript, the syntax maybe different hence why iv added 2 line within the loop.

Related

How to reverse an array in php WITHOUT using the array reverse method

I want to know how to reverse an array without using the array_reverse method. I have an array called reverse array which is the one i want to reverse. My code is below. could someone point out what i am doing wrong as I cannot find any example of reversing an array this way anywhere else. my code is below.
<?php
//Task 21 reverse array
$reverseArray = array(1, 2, 3, 4);
$tmpArray = array();
$arraySize = sizeof($reverseArray);
for($i<arraySize; $i=0; $i--){
echo $reverseArray($i);
}
?>
<?php
$array = array(1, 2, 3, 4);
$size = sizeof($array);
for($i=$size-1; $i>=0; $i--){
echo $array[$i];
}
?>
Below is the code to reverse an array, The goal here is to provide with an optimal solution. Compared to the approved solution above, my solution only iterates for half a length times. though it is O(n) times. It can make a solution little faster when dealing with huge arrays.
<?php
$ar = [34, 54, 92, 453];
$len=count($ar);
for($i=0;$i<$len/2;$i++){
$temp = $ar[$i];
$ar[$i] = $ar[$len-$i-1];
$ar[$len-$i-1] = $temp;
}
print_r($ar)
?>
The problem with your method is when you reach 0, it runs once more and index gets the value of -1.
$reverseArray = array(1, 2, 3, 4);
$arraySize = sizeof($reverseArray);
for($i=$arraySize-1; $i>=0; $i--){
echo $reverseArray[$i];
}
Here's another way in which I borrow the code from here and update it so that I eliminate having to use a $temp variable and instead take advantage of array destructuring, as follows:
<?php
/* Function to reverse
$arr from start to end*/
function reverseArray(&$arr, $start,
$end)
{
while ($start < $end)
{
[$arr[$start],$arr[$end]] = [$arr[$end],$arr[$start]];
$start++;
$end--;
}
}
$a = [1,2,3,4];
reverseArray($a,0,count($a)-1);
print_r($a);
See live code
One of the advantages of this technique is that the array $a is reversed in place so there is no necessity of creating a new array.
The following improves the code so that one need not pass more than one parameter to reverseArray(); as well as indicating that there is no return value:
/* Function to reverse
$arr from start to end*/
function reverseArray(&$arr, $start=0): void
{
$end = count($arr)-1;
while ($start < $end)
{
[$arr[$start],$arr[$end]] = [$arr[$end],$arr[$start]];
$start++;
$end--;
}
}
$a = [1,2,3,4];
reverseArray($a);
print_r($a);
See here
Note: this revision works in PHP 7.2-7.4.2
how to reverse a array without using any predefined functions in php..
i had a solution for this problem...
here is my solution........
<?php
// normal array --------
$myarray = [1,2,3,4,5,6,7,8,9];
//----------------
$arr = [];
for($i=9; $i > -1; $i--){
if(!$i==0){
$arr[]= $i;
}
}
print_r($arr);
//the out put is [9,8,7,6,5,4,3,2,1];
?>

Check if the array can be sorted with a single swap of 2 elements

I am trying to write a function that will check if the array can be sorted with a single swap of the values in the array.
For example: array(1,3,5,3,7) must return true, but array(1,3,5,3,4) must return false.
I tried the following code below, but I'm stuck with it:
$noOfIterations = 0;
for($x = 0; $x < count($a)-2; $x++) {
if($a[$x] > $a[$x+1]) {
$noOfIterations ++;
}
}
return $noOfIterations >1;
// The below solution helped as well.
//$arr = [1, 3, 5, 3, 7]; //[1, 3, 5, 3, 4]
$arr = [1, 3, 5, 3, 4];
$sortedArr = $arr;
sort($sortedArr);
print_r(array_intersect_assoc($arr,$sortedArr));
This should work for you:
(Here I first make a copy of the original array to then sort() it. After this I loop through both arrays with array_map() and look how many position has changed. With array_filter() I sort the elements out where no position has changed. Then you can simply check if 2 or more position has changed and print either FALSE or TRUE)
<?php
$arr = [1, 3, 5, 3, 7]; //[1, 3, 5, 3, 4]
$sortedArr = $arr;
sort($sortedArr);
$filtered = array_filter(
array_map(function($v1, $v2){
return ($v1 == $v2 ?FALSE:TRUE);
}, $arr, $sortedArr)
);
var_dump(count($filtered) > 2 ? FALSE : TRUE);
?>
output:
TRUE //FALSE
Execute the sort, then compare the original array with the sorted array using array_intersect_assoc().... if the difference is more than two elements, then the answer is 'no'
If you really wanna do it with a loop, you can do it with a double loop comparing each value to one another. You need to get a little creative with the comparing. From what I see, your code succeeds on the first array but fails on the second. It fails on the second one because you are only checking 2 adjacent entries and 3 is always less than 4. Or you can keep track of the largest number and count how many numbers are less than that value past it. Also make sure to add to the count if you encounter another bigger value. Hope all this makes sense.
What if array is sorted and no swap is needed?
It might help if I knew Why.
Try this, it works for your two example arrays.
function swap($array){
$prev = 0;
$count = 0;
foreach($array as $val){
if($val < $prev){
$count++;
}
else{
$prev = $val;
}
}
if($count < 2){return(true);}else{return(false);}
}
My answer in php.
function oneSwap($A){
$count=count($A);
$swaps=0;
$curr_max = 0;
$res = false;
for($i = 0; $i <= $count; $i++) {
if(isset($A[$i+1])){
if(($A[$i] >= $A[$i + 1]) && $curr_max >= $A[$i+1]){
$swaps++;
}
if($A[$i] >= $A[$i +1]){
$curr_max = $A[$i];
}
}
}
if(($swaps == 1) || ($swaps == 0 && $curr_max ==0)){
$res = true;
echo $res;
}
}
oneSwap([3,1,2,8]);
oneSwap([1,2,3]);
oneSwap([1,5,3,3,7]);
oneSwap([3,2,1,8]);
oneSwap([2,1,1,2]);

Placing integers into the next available position of an array inside of a for loop

Hi I am attempting to figure out how to iterate through integers, determine if they are prime and then put the primes in one array and the non primes into another.
I have already have the function finished for checking for primes which I will leave out for simplicity. I just can't seem to place the values into different arrays. Here is what I have so far.
Any insight on this is appreciated, I have searched through a lot of previous questions and can't seem to come up with a working answers yet, even though this seems so straight forward.
<?php
$start = 0;
$end = 1000;
$primes = array();
$nonPrimes = array();
for($i = $start; $i <= $end; $i++)
{
if(isPrime($i))
{
//add to the next available position in $primes array;
}
else
{
//add to the next available position in $nonPrimes array;
}
}
?>
array_push maybe?
if(isPrime($i))
{
//add to the next available position in $primes array;
array_push($primes,$i);
}
else
{
//add to the next available position in $nonPrimes array;
array_push($nonPrimes,$i);
}
Use the [] operator to add an element to an array:
if (isPrime($i))
{
$primes[] = $i;
}
else
{
$nonPrimes[] = $i;
}
This will result in arrays like:
$primes[2, 3, 5, 7, 11];
and
$nonPrimes[1, 4, 6, 8, 9, 10];

Using an index twice in PHP

I am trying to use a for loop where it looks through an array and tries to make sure the same element is not used twice. For example, if $r or the random variable is assigned the number "3", my final array list will find the value associated with wordList[3] and add it. When the loop runs again, I don't want $r to use 3 again. Example output: 122234, where I would want something along the lines of 132456. Thanks in advance for the help.
for($i = 0; $i < $numWords; $i++){
$r = rand(0, $numWords);
$arrayTrack[$i] == $r;
$wordList[$r] = $finalArray[$i];
for($j = 0; $j <= $i; $j++){
if($arrayTrack[$j] == $r){
# Not sure what to do here. If $r is 9 once, I do not want it to be 9 again.
# I wrote this so that $r will never repeat itself
break;
}
}
Edited for clarity.
Pretty sure you are over complicating things. Try this, using array_rand():
$final_array = array();
$rand_keys = array_rand($wordList, $numWords);
foreach ($rand_keys as $key) {
$final_array[] = $wordList[$key];
}
If $numWords is 9, this will give you 9 random, unique elements from $wordList.
See demo
$range = range(0, $numWords - 1); // may be without -1, it depends..
shuffle($range);
for($i = 0; $i < $numWords; $i++) {
$r = array_pop($range);
$wordList[$r] = $finalArray[$i];
}
I do not know why you want it.. may be it is easier to shuffle($finalArray);??
So ideally "abcdefghi" in some random order.
$letters = str_split('abcdefghi');
shuffle($letters);
var_dump($letters);
ps: if you have hardcoded array $wordList and you want to take first $n elements of it and shuffle then (if this is not an associative array and you do not care about the keys)
$newArray = array_slice($wordList, 0, $n);
shuffle($newArray);
var_dump($newArray);
You can try array_rand and unset
For example:
$array = array('one','two','free','four','five');
$count = count($array);
for($i=0;$i<$count;$i++)
{
$b = array_rand($array);
echo $array[$b].'<br />';
unset($array[$b]);
}
after you have brought the data in the array, you purify and simultaneously removing the memory array
Ok... I have NO idea why you are trying to use so many variables with this.
I certainly, have no clue what you were using $arrayTrack for.
There is a very good chance I am mis-understanding all of this though.
<?php
$numWords=10;
$wordList=array('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');
$finalArray=array();
for ($i=0; $i<$numWords; $i++) {
start:
$r=rand(0,$numWords);
$wordChoice=$wordList[$r];
foreach ($finalArray as $word) {
if ($word==$wordChoice) goto start;
}
$finalArray[]=$wordChoice;
}
echo "Result: ".implode(',',$finalArray)."\n";

How to sort it better?

I have 2 arrays, both are multidimensional with same number of elements and same values, which are on different positions (those values are actually ID-s from my database, so one ID appears only once). How can I sort second array with values which are in first array?
For example - if first array looks like:
$array1[0][0] = 1;
$array1[0][x] = it doesn't matter what's here
$array1[1][0] = 4;
$array1[1][x] = it doesn't matter what's here
$array1[2][0] = 3;
$array1[2][x] = it doesn't matter what's here
...
how to sort second array so it would have same values as array1 on indexes [0][0], [1][0], [2][0], etc.
How I could solve problem is:
$i=0
while ($i < (count($array1)-2)){ // * check down
$find_id = $array1[$i][0];
// here I need to search for index of that ID in other array
$position = give_index($find_id, $array2);
// swapping positions
$temp = array2[$i][0];
$array2[$i][0] = $array2[$position][0];
$array2[$position][0] = $temp;
// increasing counter
i++;
}
function give_index($needle, $haystack){
for ($j = 0, $l = count($haystack); $j < $l; ++$j) {
if (in_array($needle, $haystack[$j][0])) return $j;
}
return false;
}
*There is only -2 because indexes start from 0 and also for the last element you don't need to check since it would be automatically sorted by last iteration of while-loop.
I don't find this solution good as I think that this is quite simple issue (maybe it's not even correct). Is there easier way in PHP that I'm missing?
This is the most efficient way I can think of:
function swap(&$a, &$b) {
$t = $a;
$a = $b;
$b = $t;
}
function find_index($id, $array, $from = 0) {
$index = false;
for ($i = $from, $c = count($array); $i < $c; $i++) {
if ($array[$i][0] == $id) {
$index = $i;
break;
}
}
return $index;
}
for ($i = 0, $c = count($array1); $i < ($c - 2); $i++) {
if ($array1[$i][0] != $array2[$i][0]) {
$fi = find_index($array1[$i][0], $array2, $i);
swap($array2[$i][0], $array2[$fi][0]);
}
}
What changes from yours?
I've defined a swap() function in order to swap any variable. That doesn't cost anything and makes everything look nicer. Also you can reuse that function later if you need to.
In the find_index (give_index in your code) we stop the loop once we find the correct index. Also we avoid the cost of an in_array function call.
We modified the find_index function to start only from the part of the array we haven't checked yet. Leading to a way more efficient way of scan the array.
In the for loop (a while loop was just wrong there) we stored the count of the array once, avoiding multiple calls.
Also we swap the $array2 values only if they are in the wrong place.
Other improvements
If you know anything else of the $array2 array you can make this even more performant. For example if you know that indexes are alternated like in $array1 you can change the main for loop from:
for ($i = 0, $c = count($array1); $i < ($c - 2); $i++) {
to
for ($i = 0, $c = count($array1); $i < ($c - 2); $i+2) {
(notice the $i+2 at the end) And you could do that in the find_index function as well.
Look into usort (http://php.net/manual/en/function.usort.php).
It provides a simple way to sort arrays using a user provided comparison function.

Categories