I am trying to learn how to use array_unique, so I made some sample code and I didn't get what I expected.
$array[0] = 1;
$array[1] = 5;
$array[2] = 2;
$array[3] = 6;
$array[4] = 3;
$array[5] = 3;
$array[6] = 7;
$uniques = array_unique($array, SORT_REGULAR);
for($i = 0; $i < count($uniques); $i++)
echo $uniques[$i];
For example this gives me the output of '15263' but not 7. After a few test I think that it stops looking after it finds the first duplicate. Is that what is supposed to happen?
Reason for $uniques output is
Array
(
[0] => 1
[1] => 5
[2] => 2
[3] => 6
[4] => 3
[6] => 7
)
Your array doesn't contain key 5, but in your for loop echo $uniques[$i]; not hold the value of echo $uniques[5];. that is the reason value 7 is missing.
Try this,
foreach($uniques as $unique){
echo $unique;
}
instead of
for($i = 0; $i < count($uniques); $i++)
OR, you can re-index the array using array_values($uniques) and use,
$uniques = array_values($uniques);
for($i = 0; $i < count($uniques); $i++)
echo $uniques[$i];
Since array_unique preserves the keys, you can’t access the array $uniques properly with a for loop. Either use a foreach loop or change the seventh line of your code to:
$uniques = array_values(array_unique($array, SORT_REGULAR));
Related
I have a task of sorting an array of numbers in both ascending and descending order. The challenge is, I can't use the built-in sort function, but loop through the array with for-loops instead.
I am a total newbie when it comes to PHP and this task straight off baffles me. Here is the code I'm supposed to work with:
<?php
$arr = $_GET['arr'];
$table = explode(',', $arr);
$count = count($table);
// What I tried to work with, didn't get to work:
for ($i = 0; $i < $count; $i++) {
for ($j = $i + 1; $j < $count; $j++) {
if ($table[$i] > $table[$j]) {
$temp = $table[$i];
$table[$i] = $table[$j];
$table[$j] = $temp;
$asc = implode("," $temp);
}
}
}
echo "Ascending: $asc";
echo "Descending: $desc";
?>
Any clue why this doesn't run? At some point, I got the first (largest) number in the array with the echo, but don't really know what broke that either.
Move the line
$asc = implode(",", $table);
from its current location below the outer for loop and maybe add the line
$desc = implode(",", array_reverse($table));
to get the descending sort order.
Many ways to make it. One solution you will find in the code below. you will certainly notice that the sorting depends only on one operator. Therefore, you can build a function out of it by specifying the sorting as a parameter. function(array $array, string $sort) {}
DESC
$arr= array(112,21,130,140,2,42);
for($i=0; $i<count($arr)-1; $i++)
{
for($j=0; $j<count($arr)-1; $j++)
{
if($arr[$j] < $arr[$j+1]){
$temp= $arr[$j+1];
$arr[$j+1]= $arr[$j];
$arr[$j]= $temp;
}
}
}
print_r($arr);
Output:
Array
(
[0] => 140
[1] => 130
[2] => 112
[3] => 42
[4] => 21
[5] => 2
)
ASC
$arr= array(112,21,130,140,2,42);
for($i=0; $i<count($arr)-1; $i++)
{
for($j=0; $j<count($arr)-1; $j++)
{
if($arr[$j] > $arr[$j+1]){
$temp= $arr[$j+1];
$arr[$j+1]= $arr[$j];
$arr[$j]= $temp;
}
}
}
print_r($arr);
Output
Array
(
[0] => 2
[1] => 21
[2] => 42
[3] => 112
[4] => 130
[5] => 140
)
This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 3 years ago.
I am trying to create an algorithm that shows each step of bubble sort, sorting one number at a time. I was was able to sort the number at the first index, but I need to figure out how to sort all the numbers.
$x = array (9,7,5,3,0);
$count = count($x);
for($i = 0; $i < $count-1; $i++ ) {
$temp = $x[$i+1];
$x[$i+1] = $x[$i];
$x[$i] = $temp;
echo '<pre>';
print_r($x);
}
My current output is:
Array
(
[0] => 7
[1] => 9
[2] => 5
[3] => 3
[4] => 0
)
Array
(
[0] => 7
[1] => 5
[2] => 9
[3] => 3
[4] => 0
)
Array
(
[0] => 7
[1] => 5
[2] => 3
[3] => 9
[4] => 0
)
Array
(
[0] => 7
[1] => 5
[2] => 3
[3] => 0
[4] => 9
)
From here I need to continue sorting the remaining numbers. For 7, the output should be
57390
53790
53970
53907
and then for 3
35079
30579
30759
30795
and then for 0, it should be same for all 4 lines like
03570
03579
03579
03579
[The assigned problem.][1]
Two issues:
You should only swap values when they are not in the right order
You need an outer loop to repeat this inner loop, similar to a proper bubble sort algorithm.
Your code can be modified like below so it generates the required output:
$x = array (9,7,5,3,0);
$count = count($x) - 1;
for($times = 0; $times < $count; $times++) {
for($i = 0; $i < $count; $i++ ) {
$temp = $x[$i+1];
if ($temp < $x[$i]) {
$x[$i+1] = $x[$i];
$x[$i] = $temp;
}
echo implode(" ", $x) . "\n";
}
echo "\n";
}
Note that a proper bubble sort algorithm will perform fewer iterations.
Bubble sort is basically simplified into a min() + shift (or sometimes swap) operation that occurs N times. So it's an O(n^2) algorithm.
Since this is for learning purposes I'm going to try to be as verbose as possible.
function getMin(Array &$array): Int {
$min = reset($array);
$minKey = null;
// Find the minimum value
foreach($array as $k => $n) {
if ($n < $min) {
$min = $n;
$minKey = $k;
}
}
// remove the minimum value from the array
$array[$k] = null;
$array = array_filter($array, function ($v) { return $v !== null; });
return $min;
}
$array = [9,7,5,3,0];
foreach ($array as $n => $value) {
// Find the min value in the array from Nth index onward
$min = getMin($array); // get the smallest value in the array and remove it.
$sorted[] = $min; // push it on to the new array
}
var_dump($sorted);
This gives you the expect result:
array(5) {
[0]=>
int(0)
[1]=>
int(3)
[2]=>
int(5)
[3]=>
int(7)
[4]=>
int(9)
}
Of course, this is not the way you would want to implement Bubble Sort, because it's a bit circuitous. Again, it's for educational purposes. You can inspect the $array as it's being modified at each step and the new $sorted as it's being built. Typically you would just swap the min/max values in place and use the same array (keeping track of the keys to rescan the array).
Like this...
// Unsorted $array
$array = [9,7,5,3,0];
// Sort the array
for ($lastKey = $i = 0, $len = count($array); $i < $len; $i++) {
// Scan for minimum value
for ($minKey = $j = $lastKey, $min = $array[$minKey]; $j < $len; $j++) {
if ($array[$j] < $min) {
$minKey = $j;
$min = $array[$j];
}
}
// Swap the values
$swap = $array[$lastKey];
$array[$lastKey] = $min;
$array[$minKey] = $swap;
// Update the scan position
$lastKey++;
}
var_dump($array); // Gives you [0,3,5,7,9]
You are performing unconditional position swapping, but you actually need to check if movement is required.
There is no shortage of tutorials that demonstrate a bubble sort in php. A quick good lead me to this one: https://www.w3resource.com/php-exercises/searching-and-sorting-algorithm/searching-and-sorting-algorithm-exercise-6.php which can be modified for your purposes.
PHP now offers "array destructuring" which means you no longer need to use a temporary holding variable while swapping.
Code: (Demo)
$x = [9,7,5,3,0];
$count = count($x) - 1;
for ($pass = 0; $pass < $count; ++$pass) {
for ($i = 0; $i < $count; ++$i) {
if ($x[$i] > $x[$i + 1]) {
[$x[$i + 1], $x[$i]] = [$x[$i], $x[$i + 1]];
}
$results[] = implode($x);
}
$results[] = "\n";
}
echo implode("\n", $results);
I'm completely new to PHP and can't understand how to take the user input for two-dimensional arrays (2D arrays). I'm providing you with the code I've been trying. Can anyone help me?
<?php
//$handle = fopen ("php://stdin","r");
$n= 0;
$m= 0;
fscanf("%d", $n);
fscanf("%d", $m);
$a = array(n)(m);
for($i=0 ; $i < $n ; $i++){
for($j=0 ; $j < $m ; $j++ ){
fscanf("%d", $a[$i][$j]);
}
}
//fclose($handle);
?>
I expect to take input and print the array
Here is the tested snippet,
$f = fopen('php://stdin', 'r');
// read whole string for manipulation
$line = fgets($f);
// exploding data with spaces
$arr = explode(" ", $line);
$m = $arr[0]; // first int as m rows
$n = $arr[1]; // second int as n cols
// unsetting as they are already used
unset($arr[0]);
unset($arr[1]);
// resetting index of array
$arr = array_values($arr);
$result = [];
for ($i = 0; $i < $m; $i++) {
for ($j = 0; $j < $n; $j++) {
// fetching current value of array
$result[$i][$j] = current($arr);
// moving iterator to next element
next($arr);
}
}
fclose($f);
print_r($result);
next — Advance the internal pointer of an array
current — Return the current element in an array
array_values() returns all the values from the array and indexes the array numerically.
fgets — Gets line from file pointer
explode — Split a string by a string
unset — Unset a given variable
Output screen:
$:/var/www/html/dummy# php index.php
3 3 1 2 3 4 5 6 7 8 9
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[1] => Array
(
[0] => 4
[1] => 5
[2] => 6
)
[2] => Array
(
[0] => 7
[1] => 8
[2] => 9
)
)
I am trying to get an factorial value of each item in array by using this method but this outputs only one value
can any body help me finding where i am doing wrong?
function mathh($arr, $fn){
for($i = 1; $i < sizeof($arr); $i++){
$arr2 = [];
$arr2[$i] = $fn($arr[$i]);
}
return $arr2;
}
$userDefined = function($value){
$x = 1;
return $x = $value * $x;
};
$arr = [1,2,3,4,5];
$newArray = mathh($arr, $userDefined);
print_r($newArray);
You're going to need a little recursion so in order to do that you need to pass the lambda function into itself by reference:
function mathh($arr, $fn){
$arr2 = []; // moved the array formation out of the for loop so it doesn't get overwritten
for($i = 0; $i < sizeof($arr); $i++){ // starting $i at 0
$arr2[$i] = $fn($arr[$i]);
}
return $arr2;
}
$userDefined = function($value) use (&$userDefined){ // note the reference to the lambda function $userDefined
if(1 == $value) {
return 1;
} else {
return $value * $userDefined($value - 1); // here is the recursion which performs the factorial math
}
};
$arr = [1,2,3,4,5];
$newArray = mathh($arr, $userDefined);
print_r($newArray);
The output:
Array
(
[0] => 1
[1] => 2
[2] => 6
[3] => 24
[4] => 120
)
I wanted to expand on this some since you're essentially (in this case) creating an array map. This could be handy if you're doing additional calculations in your function mathh() but if all you want to do is use the lambda function to create a new array with a range you could do this (utilizing the same lambda we've already created):
$mapped_to_lambda = array_map($userDefined, range(1, 5));
print_r($mapped_to_lambda);
You will get the same output, because the range (1,5) of the mapped array is the same as your original array:
Array
(
[0] => 1
[1] => 2
[2] => 6
[3] => 24
[4] => 120
)
I want to create an array from this nested for loop
for($i = 0; $i < 2; $i++){
for($j = 0; $j < 3; $j++){
$dis = $i + $j;
createArr($dis, $i);
}
echoArr($i);
}
To do this I created a function called createArr() which receives $dis and the $i iterator.
$arr= array();
function createArr($dis, $i){
$arr= 'arr'.$i;
array_push($arr, $dis);
return $arr;
}
I want $arr to be the name of the array in this example during the first iteration of the nested for loop $i = 0. Thus I want the name of the array to be $arr0 with the array_push function pushing all the elements of $j while $i = 0 then to store into another array when the second iteration of $i when it starts at$arr1 to push the new elements of this array within $j's iteration when $i = 1;
function echoArr($i){
$arr= 'arr'.$i;
return $arr;
}
this last function is to echo the finished array after an iteration of $i is done.
I am not sure what you are expecting
$arr= 'arr'.$i;
array_push($arr, $dis);
to do, but array_push expects first parameter to be array,
but as you can see $arr is a string.
Is this what you need?
$arr = array();
for($i = 0; $i < 2; $i++){
for($j = 0; $j < 3; $j++){
$dis = $i + $j;
array_push($arr, createArr($dis, $i));
}
echoArr($i);
}
function createArr($dis, $i){
return array('arr'.$i => $dis);
}
print_r($arr);
//prints: Array ( [0] => Array ( [arr0] => 0 ) [1] => Array ( [arr0] => 1 ) [2] => Array ( [arr0] => 2 ) [3] => Array ( [arr1] => 1 ) [4] => Array ( [arr1] => 2 ) [5] => Array ( [arr1] => 3 ) )
What are you trying to achieve?
For the future pls describe what you would like to achieve so we can help you achieve it better.
Let me start with the first piece of code
You would like to echo the array. You are just echoing the column.
why build your own function to add something to an array?
and if you to do something with the return
$myarray[$i] = createArr($key,$value); //not a good solution, just for explaining.
Since I don't know what you like to achieve here an example of an array loop
$myarray = array();
for($i = 0; $i < 2; $i++){
for($j = 0; $j < 3; $j++){
$dis = $i + $j;
$myarray[$i][$j] = 'row:' . $i . ' column' . $j;
}
}
var_dump($myarray);
and the dump
array (size=2)
0 =>
array (size=3)
0 => string 'row:0 column0' (length=13)
1 => string 'row:0 column1' (length=13)
2 => string 'row:0 column2' (length=13)
1 =>
array (size=3)
0 => string 'row:1 column0' (length=13)
1 => string 'row:1 column1' (length=13)
2 => string 'row:1 column2' (length=13)