I have two arrays:
$arr1 = array(
1 => 250,
2 => 325,
3 => 741,
4 => 690
);
$arr2 = array(
1 => 110,
2 => 740,
3 => 1200,
4 => 500
);
I want to check if all $arr2 values are less than $arr1 values
There are now 2 keys [1] + [4] its less than $arr1 keys [1] + [4]
Without a foreach loop, I want to return true or false if any key from $arr2 is less than the same key from $arr1.
Here is one way to do it.
$result = (bool) array_filter(array_map(function($a, $b){
return $b < $a;
}, $arr1, $arr2));
The inner array_map returns true or false based on the comparison of corresponding values of $arr1 and $arr2. Then the outer array_filter reduces the result to only include true values. Casting the result to boolean will yield true if all values in $arr2 are greater than or equal to the corresponding $arr1 values (because array_filter will return an empty array), and false if any of them are less.
Keep in mind that avoiding a foreach loop is not more efficient for something like this. Both the array_map and array_filter functions will iterate the entire array they are given. If you use a foreach instead, you can break out of the loop as soon as you find an element that meets the condition you're looking for, which in this case would be the first iteration of the foreach loop.
Here is an example that does not use foreach() but most of us would use an iterator to work with array elements. You could use for() or while() loops, too.
<?php // demo/temp_samer.php
/**
* Compare array elements
*
* https://stackoverflow.com/questions/45422576/check-if-two-arrays-are-equal-key-value-with-same-name
*/
error_reporting(E_ALL);
echo '<pre>';
$arr1=array('1'=>250,'2'=>325,'3'=>741,'4'=>690);
$arr2=array('1'=>110,'2'=>740,'3'=>1200,'4'=>500);
if ($arr2[1] < $arr1[1]) echo PHP_EOL . "KEY 1 IS LOWER IN THE SECOND ARRAY";
if ($arr2[2] < $arr1[2]) echo PHP_EOL . "KEY 2 IS LOWER IN THE SECOND ARRAY";
if ($arr2[3] < $arr1[3]) echo PHP_EOL . "KEY 3 IS LOWER IN THE SECOND ARRAY";
if ($arr2[4] < $arr1[4]) echo PHP_EOL . "KEY 4 IS LOWER IN THE SECOND ARRAY";
This shows a way of thinking about the problem.
https://iconoun.com/demo/temp_samer.php
<?php // demo/temp_samer.php
/**
* Compare array elements
*
* https://stackoverflow.com/questions/45422576/check-if-two-arrays-are-equal-key-value-with-same-name
*/
error_reporting(E_ALL);
echo '<pre>';
$arr1=array('1'=>250,'2'=>325,'3'=>741,'4'=>690);
$arr2=array('1'=>110,'2'=>740,'3'=>1200,'4'=>500);
foreach ($arr2 as $key => $value)
{
if ($value < $arr1[$key]) echo PHP_EOL . "KEY $key IS LOWER IN THE SECOND ARRAY";
}
Related
How can I check if keys are set in an array without using multiple isset(...)
I thought of something like:
$arr1 = [
"keyA" => 1,
"keyB" => 2,
"keyC" => 3
];
$arr2 = ['keyB', 'keyD'];
$anyExists = empty(array_intersect($arr1, $arr2));
This should evaluate to true if any item of $arr2 is a key of $arr1.
It obviously does not work. But is there a similarly nice solution without using loops?
So you want to get the keys as values from the first array as it checks values and not keys, and you want !empty() to return true if it's NOT empty and false if it IS empty:
$anyExists = !empty(array_intersect(array_keys($arr1), $arr2));
You could use array_intersect_key(), but then you would need to flip the second array to get the values as keys:
$anyExists = !empty(array_intersect_key($arr1, array_flip($arr2)));
Or define your array as:
$arr2 = ['keyB' => true, 'keyD' => true];
I find disallowing multiple isset() calls to be an unfortunate requirement because it is sure to be the faster option. Additionally, by writing the calls into a loop with a conditional break or return will improve its efficiency again.
Code: (Demo)
function anyKeyExists($haystack, $needles) {
foreach ($needles as $needle) {
if (isset($haystack[$needle])) {
return true;
}
}
return false;
}
$array = [
"keyA" => 1,
"keyB" => 2,
"keyC" => 3
];
echo "noMatch: " , (int)anyKeyExists($array, ['keyD', 'keyF']) , "\n";
echo "oneMatch: " , anyKeyExists($array, ['keyB', 'keyD']) , "\n";
echo "twoMatches: " , anyKeyExists($array, ['keyA', 'keyC']) , "\n";
Output:
noMatch: 0
oneMatch: 1
twoMatches: 1
If you must use functional programming, you can avoid the empty() call after intersecting the keys by merely casting the output array as a boolean using !! or (bool).
Code: (Demo)
$array = [
"keyA" => 1,
"keyB" => 2,
"keyC" => 3
];
echo "noMatch: " , (int)!!array_intersect_key($array, array_flip(['keyD', 'keyF'])) , "\n";
echo "oneMatch: " , !!array_intersect_key($array, array_flip( ['keyB', 'keyD'])) , "\n";
echo "twoMatches: " , !!array_intersect_key($array, array_flip(['keyA', 'keyC'])) , "\n";
(Same output as previous snippet)
P.s. It should be obvious, but in case it is not, I'll explain that my techniques are returning true or false evaluations. I am casting the false outcomes as (int) so that they are expressed as 0 values instead of empty strings. true, when echoed, is represented as a 1.
I have been trying to match a string with the values in an array and output the array strings starting from the string with the highest character match count. for example:
$array = array(
'mike'=>'book21',
'ben'=>'buzz',
'jack'=>'airdrone',
'july'=>'march',
'fred'=>'blend45'
);
$string = 'blenmaio2';
As you can see, 'blend45', has the highest matched characters, with a total of 4 matched characters. I want to be able to output them starting from the first four highest match count, here is an example of the output i want:
blend45
book21
march
buzz
This is my first time trying to help someone, so hopefully this does the trick. I know you can probably simplify the code a little, but this is what I have.
<?php
$array = array(
'mike'=>'book21',
'ben'=>'buzz',
'jack'=>'airdrone',
'july'=>'march',
'fred'=>'blend45'
);
$string = 'blenmaio2';
$sort_array=array(); //Empty array
foreach ($array as $key => $value){
$num = similar_text($value,$string); //Using similar text to compar the strings.
$sort_array[$value] = $num; //Adding the compared number value and sring value to array.
}
arsort($sort_array, SORT_REGULAR);//Sorting the array by the larges number.
print_r ($sort_array);
//creating another foreach statement to get the output you wanted.
$count = 0;
foreach($sort_array as $key => $value){
$count++;
echo $count.". ".$key."\n";
};
?>
Results:
Array
(
[blend45] => 4
[book21] => 3
[airdrone] => 3
[march] => 2
[buzz] => 1
)
1. blend45
2. book21
3. airdrone
4. march
5. buzz
I think the levenshtein() function would be the most appropriate method to achieve your goal:
$array = array(
'mike'=>'book21',
'ben'=>'buzz',
'jack'=>'airdrone',
'july'=>'march',
'fred'=>'blend45'
);
$string = 'blenmaio2';
uasort($array, function($a, $b) use ($string) {
$aDistance = levenshtein($string, $a);
$bDistance = levenshtein($string, $b);
return ($aDistance < $bDistance) ? -1 : 1;
});
print_r($array);
// Output:
// Array
// (
// [fred] => blend45
// [july] => march
// [mike] => book21
// [ben] => buzz
// [jack] => airdrone
// )
http://php.net/levenshtein
Update Use uasort() instead of usort() to preserve the array keys.
I just noticed that my answer compares the similarity, but doesn't meet the highest character count match, so sorry for that :)
Here you are my answer. It is a bit different, because I'm using levenshtein function for finding nearest between two words.
I'm using uasort to reorder the array in way you liked.
Of course you can replace the algorithm for nearest by your function.
<?php
$array = array(
'mike'=>'book21',
'ben'=>'buzz',
'jack'=>'airdrone',
'july'=>'march',
'fred'=>'blend45'
);
$string = 'blenmaio2';
function cmp($a,$b){
global $string;
$aa=levenshtein($a, $string);
$bb=levenshtein($b, $string);
if($aa>$bb)
return 1;
elseif($bb>$aa)
return -1;
else return 0;
}
uasort($array,cmp);
?>
<pre><?= print_r($array); ?></pre>
Is there any kind of function or quick process for comparing two arrays in PHP in a way that if the value of one array exists as a key in the second array, the second array maintains its key's value, otherwise that key's value gets set to 0.
For example,
$first_array = array('fred', 'george', 'susie');
$second_array = array(
'fred' => '21',
'george' => '13',
'mandy' => '31',
'susie' => '11'
);
After comparing the two, ideally my final array would be:
Fred > 21
George > 13
Mandy > 0
Susie > 11
Where Mandy was set to 0 because the key didn't exist as a value in the first array…..
I know it's probably kind of an odd thing to want to do! But any help would be great.
foreach ($second_array as $key=>$val) {
if (!in_array($key, $first_array))) {
$second_array[$key] = 0;
}
}
Although you may want to build the first array as a set so that the overall runtime will be O(N) instead of O(N^2).
foreach($second_array as $name => $age) {
if(in_array($name, $first_array) {
//whatever
}
else {
//set the value to zero
}
}
// get all keys of the second array that is not the value of the first array
$non_matches = array_diff(array_keys($second_array), $first_array);
// foreach of those keys, set their associated values to zero in the second array
foreach ($non_$matches as $match) {
$second_array[$match] = 0;
}
foreach is more readable, but you can also use the array functions:
array_merge($second_array,
array_fill_keys(array_diff(array_keys($second_array),
$first_array),
0));
# or
array_merge(
array_fill_keys(array_keys($second_array), 0),
array_intersect_key($second_array, array_flip($first_array)));
# or
function zero() {return 0;}
array_merge(
array_map('zero', $second_array),
array_intersect_key($second_array, array_flip($first_array)));
I have a multi-dimensional array like
Array
(
[0] => Array
(
[ename] => willy
[due_date] => 12:04:2011
[flag_code] => 0
)
[1] => Array
(
[Father] => Thomas
[due_date] => 13:04:2011
[flag_code] => 0
)
[2] => Array
(
[charges] => $49.00
)
)
i want to display values of array using php. but still fail. please any one help me to do this task....?
Since you're so adamant that this be accomplished using only for loops, I have to assume this is a homework question. Because of this, I'll point you to several PHP manual pages in the hopes that you'll review them and try to learn something for yourself:
Arrays
For Loops
Foreach Loops
Now, I'm going to break your actual question a few different questions:
Is it possible to display a multidimensional array using for loops?
Yes. It's entirely possible to use a for loop to iterate over a multidimensional array. You simply have to nest for loops inside for loops. i.e. you create a for loop to iterate over the outer array, then inside that loop you use another for loop to iterate over the inner array.
How can I iterate over a multidimensional array using a for loop?
Generally, when you use a for loop, the loop will look something like this:
for($i = 0; $i < $maxValue; $i++) {
// do something with $1
}
While this works well for indexed arrays (i.e. arrays with numeric keys), so long as they have sequential keys (i.e. keys which use each integer in order. for example, an array with keys 0, 1, and 2 is sequential; an array with keys 0, 2, and 3 is not because it jumps over 1), this doesn't work well for associative arrays (i.e arrays with text as keys - for example, $array = array("abc" = 123);) because these arrays won't have keys with the numerical indexes your for loop will produce.
Instead, you need to get a bit creative.
One way that you could do this is to use array_keys to get an indexed array of the keys your other array uses. For example, look at this simple, one-dimensional array:
$dinner = array(
"drink" => "water",
"meat" => "chicken",
"vegetable" => "corn"
);
This array has three elements, each with an associative key. We can get an indexed array of its keys using array_keys:
$keys = array_keys($dinner);
This will return the following:
Array
(
[0] => drink
[1] => meat
[2] => vegetable
)
Now, we can iterate over the keys, and use their values to access the associative keys in the original array:
for($i = 0; $i < count($keys); $i++) {
echo $dinner[$keys[$i]] . "";
}
As we iterate over this loop, the index $i will be set to hold each index of the $keys array. The associated element of this key will be the name of a key in the $dinner array. We then use this key name to access the $dinner array elements in order.
Alternatively, you could use a combination of the reset, current and next functions to iterate over the values in the array, for example:
for($element = current($dinner);
current($dinner) !== false;
$element = next($dinner)
) {
echo $element . "<br />";
}
In this loop, you initialize the $element variable to be the first element in the array using reset, which sets the array pointer to the first element, then returns that element. Next, we check the value of current($dinner) to ensure that there is a value to process. current() returns the value of the element the array pointer is currently set at, or false if there is no element there. Finally, at the end of the loop, we use next to set the array pointer ahead by one. next will return false when we try to read beyond the end of the array, but we ignore that and wait for current to notice that there is no current element to stop the loop.
Now, having written all of that, there really isn't any reason to do jump through all these hoops, since PHP has the built-in foreach construct which allows you to iterate over each of an arrays elements, regardless of key type:
foreach($dinner as $key => $value) {
echo "The element in key '" . $key . "' is '" . $value ."'. <br />";
}
This is why I'm assuming this is a homework assignment, since you would probably never have reason to jump through these hoops in a production environment. It is, however, good to know that such constructs exist. For example, if you could use any loop but a foreach, then it would be a lot simpler to just use a while loop than to try to bash a for loop into doing what you want:
reset($dinner);
while (list($key, $value) = each($dinner)) {
echo "The value of '" . $key . "' is '" . $value . "'.<br />";
}
In summary, to iterate over a multidimensional array with associative keys, you would need to nest loops inside each other as shown in the answer to the first question, using one of the loops shown in the answer to the second question to iterate over the associative key values. I'll leave the actual implementation as an exercise for the reader.
To print the values of a array, you can use the print_r function:
print_r($array);
This saves a for-loop.
Just use the handy function print_r
print_r($myarray);
If you don't want to use the print_r function, then for a true n-dimensional array solution:
function array_out($key, $value, $n) {
// Optional Indentation
for($i=0; $i < $n; $i++)
echo(" ");
if(!is_array($value)) {
echo($key . " => " . $value . "<br/>");
} else {
echo($key . " => <br/>");
foreach($value as $k => $v)
array_out($k, $v, $n+1);
}
}
array_out("MyArray", $myArray, 0);
Not sure if its possible to do with a for loop and mixed associative arrays, but foreach does work just fine.
If you have to do it with a for loop, you want the following:
$count = count($array)
for($i = 0; $i <= $count; $i++)
{
$count2=count($array[$i]);
for($j = 0; $j <= $count2; $j++)
{
print $array[$i][$j] . "<br/>";
}
}
foreach( $array as $row ) {
$values = array_values($row);
foreach( $values as $v ) {
echo "$v<br>";
}
}
Should output:
willy
12:04:2011
0
Thomas
13:04:2011
0
$49.00
This will actually be readable:
echo '<pre>';
print_r($myCoolArray);
echo '</pre>';
You would need to do it using something like assigning array_keys to an array, then using a for loop to go through that, etc...
But this is exactly why we have foreach - it would be quicker to write, read and run. Can you explain why it must be done with for?
How can I get the current element number when I'm traversing a array?
I know about count(), but I was hoping there's a built-in function for getting the current field index too, without having to add a extra counter variable.
like this:
foreach($array as $key => value)
if(index($key) == count($array) ....
You should use the key() function.
key($array)
should return the current key.
If you need the position of the current key:
array_search($key, array_keys($array));
PHP arrays are both integer-indexed and string-indexed. You can even mix them:
array('red', 'green', 'white', 'color3'=>'blue', 3=>'yellow');
What do you want the index to be for the value 'blue'? Is it 3? But that's actually the index of the value 'yellow', so that would be an ambiguity.
Another solution for you is to coerce the array to an integer-indexed list of values.
foreach (array_values($array) as $i => $value) {
echo "$i: $value\n";
}
Output:
0: red
1: green
2: white
3: blue
4: yellow
foreach() {
$i++;
if(index($key) == $i){}
//
}
function Index($index) {
$Count = count($YOUR_ARRAY);
if ($index <= $Count) {
$Keys = array_keys($YOUR_ARRAY);
$Value = array_values($YOUR_ARRAY);
return $Keys[$index] . ' = ' . $Value[$index];
} else {
return "Out of the ring";
}
}
echo 'Index : ' . Index(0);
Replace the ( $YOUR_ARRAY )
I recently had to figure this out for myself and ended up on a solution inspired by #Zahymaka 's answer, but solving the 2x looping of the array.
What you can do is create an array with all your keys, in the order they exist, and then loop through that.
$keys=array_keys($items);
foreach($keys as $index=>$key){
echo "position: $index".PHP_EOL."item: ".PHP_EOL;
var_dump($items[$key]);
...
}
PS: I know this is very late to the party, but since I found myself searching for this, maybe this could be helpful to someone else
an array does not contain index when elements are associative. An array in php can contain mixed values like this:
$var = array("apple", "banana", "foo" => "grape", "carrot", "bar" => "donkey");
print_r($var);
Gives you:
Array
(
[0] => apple
[1] => banana
[foo] => grape
[2] => carrot
[bar] => donkey
)
What are you trying to achieve since you need the index value in an associative array?
There is no way to get a position which you really want.
For associative array, to determine last iteration you can use already mentioned counter variable, or determine last item's key first:
end($array);
$last = key($array);
foreach($array as $key => value)
if($key == $last) ....