i hace this issue whit two arrays
one array is given by a json like this
array1( [0] => 6, [1] => 1)
and making a query i got this other
array2( [0] => 1, [1] => 1)
I want to compare both arrays and use "if" when numeric values of array1 are less than or equal to array2. Is that possible? like this?
if($array1 <= $array2){do something}
Grettings!
This really depends on what your expected behaviour is, and also the expectations of your two arrays. For the sake of these examples, I'm going to assume that each array is guaranteed to be the same size and you are compairing paired elements (elements from each array at the same index).
If you want to exit the first time a number from array1 is less than its paired element from array2:
for ($i = 0; $i < sizeof($array1); $i++) {
if ($array1[$i] <= $array2[$i]) {
...do something
}
}
If you want to do something if all values of array1 are less than their paired elements from array2:
// Keep track of a flag so we know if we meet our condition once done
$allValuesLessThan = true;
// Check each individual array1 element and its 'paired element' from array2
for ($i = 0; $i < sizeof($array1); $i++) {
// If we break our condition, set our flag and break out of our loop, since we no longer need to check subsequent elements
if ($array1[$i] > $array2[$i]) {
$allValuesLessThan = false;
break;
}
}
// Finally, only do our 'something' if our condition was met
if ($allValuesLessThan) {
...do something
}
Related
I have an array similar to this:
$stuff = array("a"=>"115","b"=>"0","c"=>"1","d"=>"0","e"=>"11","f"=>"326","g"=>"9","h"=>"1","i"=>"12","j"=>"0","k"=>"56");
What I want to do is concatenate the strings of the keys only where they are consecutive and their values are under 10 - note this includes keeping solitary keys with values under 10 too. I don't need to keep the actual values. In other words, the desired result in this case would be:
Array ( [0] => bcd [1] => gh [2] => j)
So there might be just two consecutive keys that need to be joined, or there might be more (eg as many as 5). I'm not sure how to 'look ahead' through the array to achieve this.
You don't need to look ahead but keep the past in mind.
$consecutive = '';
foreach($stuff as $k => $v) {
if ($v < 10) // or what ever condition you need
$consecutive .= $k;
else {
if ($consecutive) $res[] = $consecutive; // if exist add it
$consecutive= ''; // and reset
}
}
if ($con) $res[] = $con; //adding last element if exist as #Joffrey comment
Now $res will be your desire output
Live example: 3v4l
This is my Associative Array:
$vetor = array(
"Name"=> "myName",
"Tel"=> "555-2020",
"Age"=> "60",
"Gender"=> "Male"
);
How I can show only three elements using the loop for?
I tried this:
for($i=0; $i<=2; $i++){
echo $vetor[$i]."<br>";
}
But without success. How I can do this?
You referring to wrong indexes because to reference the first element on your array you have to do something like : $vetor["Name"] instead of $vetor[0]
$i = 0;
foreach($vetor as $key => $value){
if($i == 2){ break; }
echo $value;
$i++;
}
foreach makes more sense for an array like this, but if you want to use for for whatever reason, the problem you'll have is that the array doesn't have sequential numeric indexes that correspond to your loop increment variable. But there are other ways to iterate over the first three elements without knowing what the indexes are.
// this first step may not be necessary depending on what's happened to the the array so far
reset($vetor);
$times = min(3, count($vetor));
for ($i = 0; $i < $times; $i++) {
echo current($vetor).'<br>';
next($vetor);
}
If next moves the internal array pointer beyond the last array element, current($vetor) will return false, so setting $times using min with the number of times you want and the array count will prevent you from looping more times than there are items in the array.
Another way, if you don't care what the keys are, is to use array_values to convert the array keys to numbers.
$vetor = array_values($vetor);
for ($i=0; $i < 3; $i++) {
echo $vetor[$i].'<br>';
}
I want unset all value from this array, but result only remove half
Ex 1:
$filter = array("English", "Malay", "Student Pass", "NRIC");
for($i=0; $i<count($filter); $i++){
unset($filter[$i]);
}
print_r($filter);
=> Result Array ( [2] => Student Pass [3] => NRIC )
Ex 2:
$filter = array("English", "Malay");
for($i=0; $i<count($filter); $i++){
unset($filter[$i]);
}
print_r($filter);
=> Result Array ( [1] => Malay )
Your problem is that every time your for loop runs, it recalculates the array's length with count($filter). Thus, the for loop runs less often than there are elements within the array. Instead you should determine the array's length ahead of the loop and only use this variable within the loop:
e.g.:
<?
$filter = array("English", "Malay", "Student Pass", "NRIC");
$arrayLength = count($filter); // contains the initial length of the array
for($i=0; $i<$arrayLength;$i++) {
unset($filter[$i]);
}
print_r($filter);
?>
However, regarding overall performance it might be better to overwrite the array or even unset it.
e.g.:
// Overwrite it with an empty array
$filter = array();
// Unset it
unset($filter);
Its because when you unset the item on the array it removes it. So on the next iteration the count($filter) has now gone down. You could do as #Daan suggested and just set $filter = array(). However if you insisted on calling unset you should loop over the array in reverse order.
for($i = count($filter) - 1; $i >= 0; $i--) {
unset($filter[$i]);
}
Each time you unset an element, count($filter) decreases. Let me give you an example:
You have six apples. You are eating the n'th apple while n is smaller than the number of apples. So, you eat the 0'th apple, because 0 < 6. You have 5 apples. You eat the 1st apple, because 1 < 5. You have 4 apples. You eat the 2nd apple, because 2 < 4. You have 3 apples. You don't eat the 3rd apple, since 3 < 3 is not true. As a result, three apples will remain. Your mistake was assuming that the ever incremented index is slower than the ever decremented count if and only if the array is not empty. This is wrong and you need a different approach, like this:
while (count($filter) > 0) {
unset($filter[count($filter) - 1]);
}
This is sub-optimal though, just unset the array instead, like this:
unset($filter);
I have a multidimensional array which has some predictable key and some unpredictable.
An example would be:
$myarray[0] => array ( [prefix-number] => value ... )
$myarray[1] => array ( [prefix-number] => value ... )
The first part of the array will always start at 0 and go up from there... that is by design. The second part of the array has a set prefix which is a label which is predictable but the number after the dash is not. For array entry 0 it could be number 3 or 6. For entry 0 all numbers will be the same. What I'm looking to do is a for statement that will go through each element in the array checking the sub key prefixes but not worry about the number... for example:
for($i = 0; $i < count($myarray); $i++) {
if($myarray[$i]['prefix-'%] == "") {
$error = "error";
}
}
I want the % in there to be a wildcard where the if statement won't worry about what is there just the prefix which is in quotes.
I realize I can use substr on the array key and get just the prefix out but I was hoping that wildcards were allowed in some way.
Thanks for the criticism!
I ended up storing the second key in a variable so it looks like:
$arraykey = key($myarray[$i]);
if($myarray[$i][$arraykey] == "") { ....
What I'm trying to do: Compare an array value which is an object with other objects in the array. If certain object properties in the needle (the object I'm comparing against the other objects) match the same properties in another object in the haystack, then merge certain properties from the needle to the matched object in the haystack and unset the needle.
Some pseudo-code:
<?php
$haystack = array($obj1, $obj2, $obj3);
if(!empty($haystack)){
for($x=0;$x<count($haystack);$x++){
if($haystack[$x]->prop1 == $haystack[$x+1]->prop1 && $haystack[$x]->prop2 == $haystack[$x+1]->prop2){
$haystack[$x]->combined1 = $haystack[$x]->prop1.','.$haystack[$x+1]->prop1;
unset($haystack[$x+1]);
}
}
}
?>
Expanding a tad on my comment:
You'll have to change unset($haystack[$x+1]); to unset($haystack[++$x]);
If, say indexes 0 and 1 are equal, your current loop unsets $haystack[1], keeping the value of $i at 0, the loop then continues to increment $i with 1 (to 1 in this case), and executes the comparison with $haystack[1], which has just been unset.
Actually incrementing $i means that, at the end of the loop $i will be 1, instead of 0. That will be incremented once more, and the next time around, the loop will compare indexes 2 and 3.
for ($x = 0, $max = count($haystack);$x <$max;++$x)
{
if ($haystack[$x] == $haystack[$x+1])
{//only increment if you unset!
unset($haystack[++$x]);
}
}
That should do the trick. If you want to compare all elements in the given array, then you'll have to nest two loops:
for ($x = 0, $max = count($haystack);$x <$max;++$x, $max =count($haystack))
{//re-assign $max after inner loop completes, and reset keys
for ($j = $x+1;$j<$max;++$j)
{
if ($haystack[$x] == $haystack[$j])
{//No need to increment again
unset($haystack[$j]);
}
}
$haystack = array_values($haystack);//this resets the keys
}
That should solve your problem
Solution
for($x=0;$x<count($haystack);$x++){
for($y=0;$y<=count($haystack);$y++){
if($haystack[$x]->prop1 == $haystack[$y]->prop1 && $haystack[$x]->prop2 == $haystack[$y]->prop2){
if($haystack[$x]->prop3 == $haystack[$y]->prop3){
continue;
}else{
$haystack[$x]->prop1 .= $haystack[$y]->prop1;
unset($haystack[$y]);
}
}
}
}
In retrospect, this was a fairly easy problem to solve. The issue was trying to mentally keep the iterators straight and knowing how many were needed. In order for this to work without copying the array or using an intermediary, you just need to instantiate two iterators to iterate over the array simultaneously so you can compare $array[0-n] to $array[0-n] instead of comparing $array[0-n] to $arrayCopy[0-n].