php array numbers comparison - php

Let's say I have
$input = ['1, 2, 3, 4, 5'];
and I need to get every number in the array that are stored as a string. Is there any possible way to use foreach() or anything else for every number in that string? In other words to retrieve numbers from string.
Thanks in advance!

Use explode() to split the string into numbers.
foreach ($input as $numberstring) {
$numbers = explode(', ', $numberstring);
foreach ($numbers as $number) {
...
}
}

I have changed the input array, because quotes dont make sense in terns of the question, let me know if this is wrong.
$input = [1, 2, 3, '4', 5];
foreach($input as $i){
if(is_string($i)){//test if its a string
$strings[]=$i; //put stings in array (you could do what you like here
}
}
print_r($strings);
output:
Array
(
[0] => 4
)
your input is a single array element with one string of comma separated numbers
$input = ['1, 2, 3, 4, 5'];

For your example data, you could loop the array and check if the item from the array is a string using is_string. In your example the numbers are separated by a comma so you could use explode and use a comma as the separator.
Then you could use is_numeric to check the values from explode.
$input = ['1, 2, 3, 4, 5', 'test', 3, '100, a, test'];
foreach ($input as $item) {
if (is_string($item)) {
foreach (explode(',', $item) as $i) {
if (is_numeric($i)) {
echo trim($i) . "<br>";
}
}
}
}
Demo
That would result in:
1
2
3
4
5
100

Related

How to save array variables in antoher array PHP

I am making question like 3 * 5 = ? and ? * 5 = 15. To make this, I will save an array variable ($arrayTotalQuestions) with the number 1 to 10 and an array variable ($arrayAnswers)
with the number 5,10,15,20,25,30,35,40,45,50 inside $array1. I will loop these 2 rows 20 times in my table like this:
foreach($array1 as $array1) {
echo $array1[array_rand($array1)];
}
The (array)variables inside the array:
$arrayTotalQuestions = range(1, 10);
$number = 5;
$arrayAnswers = (5, 10, 15, 20, 25, 30, 35, 40, 45, 50);
Now I want to store these 3 variables inside another array named $array1:
$array1 = array(
"<tr><td>$this->arrayTotalQuestions</td> <td>x</td> <td>$this->number</td> <td>=</td> <td><input type='text' name='txtAnswer[$this->arrayTotalQuestions]'></td></tr>",
"<tr><td><input type='text' name='txtAnswer[$this->arrayAnswers]' value=''></td> <td>x</td> <td>$this->number</td> <td>=</td> <td>$this->arrayAnswers</td></tr>"
);
But I am getting the error "array to string conversion...", because of the array variables inside $array1.
How can I solve this?
Like the error says you're trying to convert an array to a string, which isn't possible.
Take a look at this example:
<?php
$array = [1,2,3,4,5];
$newVar = "This is my array: $array";
?>
This results in the error E_NOTICE : type 8 -- Array to string conversion -- at line 3.
You're trying to output an array, which has multiple values in it, as part of your string. PHP doesn't know how you want to do this (should it just list all the array vars? Does it put a space between them? A comma? A comma and a space? etc)
So, instead, you need to convert the array into a string yourself. One way you can do this is to use the join() function in PHP.
join() takes 2 parameters: separator and array and outputs a string which is all the array values separated by your separator.
So the above example becomes:
<?php
$array = [1,2,3,4,5];
$newVar = "This is my array: ".join(", ", $array);
?>
Which outputs This is my array: 1, 2, 3, 4, 5
Updated based on comment
To use 2 or more arrays in the same foreach loop you just need to change it into a for loop:
for($i = 0, $i < count($array1); $i++) {
echo $array1[$i].': '.$array2[$i];
}
There is a way to do it with a foreach loop too, but I find that this isn't quite as clean a way to do this for maintenance (just my preference).
foreach($array1 as $index => $value) {
echo $value.': '.$array2[$index];
}

How can I remove the current element in a foreach loop from the array, without changing the original array?

How can I get a new array with all elements except the current element passed into the foreach loop. See example below:
$numbers = [1, 2, 3, 4, 5];
foreach($numbers as $numer){
// Get a new array with 4 elements excluding the $numer
// For example for first loop I want a array [2, 3, 4, 5]
}
I tried doing:
foreach($numbers as $i=>$numer) {
unset($numbers[$i]);
echo '<pre>';
var_dump($numbers);
echo '</pre>';
}
It works but it alters original array. Is there any PHP function to get new array without affecting original one?
$numbers = array(1,2,3,4,5);
if (($key = array_search($numer, $numbers)) !== false) {
unset($numbers[$key]);
}
If you want to delete all instances of $numer, simply replace if with while.
Edit: I see you've changed your question to include not changing the original array. You can copy the array and manipulate the copied array in that case.
This should work for you:
Just use array_diff_key() to get the entire array, expect the current element, e.g.
<?php
$numbers = [1, 2, 3, 4, 5];
foreach($numbers as $key => $numer){
print_r(array_diff_key($numbers, array_flip([$key])));
}
?>
EDIT:
If you don't have the key, you can simply use array_keys() to get all keys, e.g.
$numbers = [1, 2, 3, 4, 5];
$value = 32;
print_r(array_diff_key($numbers, array_flip(array_keys($numbers, $value))));
This will work
<?php
$numbers = array(1,2,3);
foreach($numbers as $index => $value){
$temp = $numbers;
unset($temp[$index]);
$new_array = $temp;
echo '<pre>'.print_r($new_array, true).'</pre>';
}
?>

Issues with in_array

I have the following fairly simple code, where I need to determine if a certain value exists in an array:
$testvalue = $_GET['testvalue']; // 4
$list = '3, 4, 5';
$array = array($list);
if (in_array($testvalue, $array)) { // Code if found } else { // Code if not found }
Even though it is obvious that the number 4 is in the array, the code returns the code inside the else bracets. What have I done wrong?
Change the third line:
$array = array_map('trim', explode(',',$list));
$array here is:
$array = array('3, 4, 5');
which is not the same as:
$array = array(3, 4, 5);
So, fix the way you are creating this array.. don't do it from a string.
Your array contains just one value, the string 3, 4, 5.
See the example on CodePad.
If you want to convert your string in an array, you can use:
$array = explode(', ', $list);
I have added a space behind the comma, but a safer method would be to use just a comma and then trim all values.

Filter array to retain rows with smallest element count and unique first and last elements

I want to remove rows from my array so that my result is an array that contains rows with unique first and last elements. If two (or more) rows have the same first and last value, I want to preserve the row with the lowest element count.
Say I have the following array:
$var = [
[1, 2, 3],
[1, 3],
[1, 2, 4, 3],
[1, 3, 4]
];
What I want is to remove all arrays from $var that have the first and last element the same as another array from $var but have more elements.
Because the first three rows all start with 1 and end with 3, only the second row containing [1, 3] should be kept.
The fourth row ([1, 3, 4]) uniquely starts with 1 and ends with 4, so it should also be kept.
The output should be:
[
[1, 3],
[1, 3, 4]
]
I am looking for the most efficient way of doing this, both in terms of memory and time. $var may have up to 100 arrays, and each individual array may have up to 10 elements in it. I thought of using some kind of comparison between all two elements (for(i=0;...) for(j=i+1;...) complexCompareFunction();), but I believe this isn't very efficient.
use current and end
$all = array();
foreach ($var as $idx=>$arr):
$first = current($arr);
$last = end($arr);
$size = count($arr);
$key = $first.'.'.$last;
if (isset($all[$key])):
if ($size > $all[$key]):
unset($var[$idx]);
else:
$all[$key] = $size;
endif;
else:
$all[$key] = $size;
endif;
endforeach;
ops ... you can iterate (again) at the end to ensure the already reduced sized array can be further removed
In general, yes, you are too worried about efficiency (as you wondered in another comment). Though PHP is not the most blisteringly-fast language, I would suggest building the most straightforward solution, and only worry about optimizing it or streamlining it if there is a noticeable issue with the end result.
Here is what I would do, off the top of my head. It is based off of ajreal's answer but hopefully will be easier to follow, and catch some edge cases which that answer missed:
// Assume $var is the array specified in your question
function removeRedundantRoutes( $var ){
// This line sorts $var by the length of each route
usort( $var, function( $x, $y ){ return count( $x ) - count( $y ); } );
// Create an empty array to store the result in
$results = array();
// Check each member of $var
foreach( $var as $route ){
$first = $route[0];
$last = $route[ count( $route ) - 1 ];
if( !array_key_exists( "$first-$last", $results ) ){
// If we have not seen a route with this pair of endpoints already,
// it must be the shortest such route, so place it in the results array
$results[ "$first-$last" ] = $route;
}
}
// Strictly speaking this call to array_values is unnecessary, but
// it would eliminate the unusual indexes from the result array
return array_values( $results );
}
Here is how I would group by a temporary key (formed by creating a delimited string from the first and last value in a given row) and conditionally push qualifying data into a result array. When the loop finishes, extract the second column from the result array to produce an indexed array containing only the smallest of qualifying rows. No pre-sorting required.
Code: (Demo)
$result = [];
foreach ($array as $row) {
$cache = [count($row), $row];
array_splice($row, 1, -1);
$key = implode('-', $row);
if (!isset($result[$key]) || $cache[0] < $result[$key][0]) {
$result[$key] = $cache;
}
}
var_export(array_column($result, 1));
Alternative Code: (Demo)
$result = [];
foreach ($array as $row) {
$count = count($row);
$key = $row[0] . '-' . $row[array_key_last($row)]; // or array_pop($row)
if (!isset($result[$key]) || $count < $result[$key][0]) {
$result[$key] = [$count, $row];
}
}
var_export(array_column($result, 1));
Output:
array (
0 =>
array (
0 => 1,
1 => 3,
),
1 =>
array (
0 => 1,
1 => 3,
2 => 4,
),
)

PHP arsort issue with keys

$vals = array(51, 23, 77, 3, 8, 31, 17, 102, 87);
arsort($vals);
From here, how can I get the keys of the 3 first values? If I do $vals[0] it won't work because it'll return me the original [0] key before the arsort.
I want to get the original keys of 102, 87 and 77 after arsort.
Depending on what you need it for, one way is
$keys = array_keys($vals);
$keys[0] will contain the first key.
$vals[$keys[0]] will contain the first value.
An alternate way
$part = array_slice($vals, 0, 3, true);
$part will contain three $key => $value pairs for the first three entries.
And for the first three keys, you can mix and match the above, such as:
$firstThree = array_keys(array_slice($vals, 0, 3, true));
$firstThreeKeys = array_slice(array_keys($vals), 0, 3);
echo join(', ', $firstThreeKeys);
I think I have found a method, maybe not the best however:
reset($arr); $key1=key($arr);
next($arr); $key2=key($arr);
next($arr); $key3=key($arr);
You could use array_keys()?
Alternatively, loop through the sorted array with a foreach and you can still get the keys:
$i = 0;
$numKeysToGet = 3;
$keys = array();
foreach ($vals as $k => $v) if ($i < $numKeysToGet) {
$keys[] = $k;
$i++;
} else break;
// $keys now contains the first three array keys
arsort saves key=>value relationship, so it's usualy used for associative arrays (hash). For your needs try to sort value=>key array instead of your key=>value with the standart sotring function. Otherwise you can use foreach loop (limit it with 3 iterations) to get the keys.

Categories