(PHP) Checking items in an array - php

I have an array like this:
Array(a,b,c,a,b)
Now, if I would like to check how many instances of "b" I can find in the array, how would I proceed?

See the documentation for array_count_values(). It seems to be what you are looking for.
$array = array('a', 'b', 'c', 'a', 'b');
$counts = array_count_values($array);
printf("Number of 'b's: %d\n", $counts['b']);
var_dump($counts);
Output:
Number of 'b's: 2
array(3) {
["a"]=> int(2)
["b"]=> int(2)
["c"]=> int(1)
}

Use array_count_values($arr). This returns an associative array with each value in $arr as a key and that value's frequency in $arr as the value. Example:
$arr = array(1, 2, 3, 4, 2);
$counts = array_count_values($arr);
$count_of_2 = $counts[2];

You can count the number of instances by using this function..
$b = array(a,b,c,a,b);
function count_repeat($subj, $array) {
for($i=0;$i<count($array);$i++) {
if($array[$i] == $subj) {
$same[] = $array[$i]; //what this line does is put the same characters in the $same[] array.
}
return count($same);
}
echo count_repeat('b', $b); // will return the value 2

Although there are some fancy ways, a programmer should be able to solve this problem using very basic programming operators.
It is absolutely necessary to know how to use loops and conditions.
$count = 0;
$letters= array("a","b","c","a","b");
foreach ($letters as $char){
if ($char == "b") $count = $count+1;
}
echo $count.' "b" found';
NOT a rocket science.

Related

How to optimize multiple if check for array index check and initialize value 1

I have a string which has "23:22:0"
$string = "23:22:0";
$array = explode(":", $string);
if ($array[0] == 0) {
$array[0] = 1;
}
if ($array[1] == 0) {
$array[1] = 1;
}
if ($array[2] == 0) {
$array[2] = 1;
}
How to avoid multiple if condition check here and i need this condition to be optimised in some best way. Any help is appreciated thanks in advance.
Please check below example. I have commented out your $string variable and tested $string with '0:0:0' value.
Added print_r() to check whether the value is correct or not as we are expecting.
Hope it might be helpful.
//$string = "23:22:0";
$string = "0:0:0";
$array = explode(":", $string);
$array = array(
0 => ($array[0] == 0) ? 1 : $array[0],
1 => ($array[1] == 0) ? 1 : $array[1],
2 => ($array[2] == 0) ? 1 : $array[2],
);
print_r($array);
I wrote this answer because I thought there was an unknown number of items.
OP has now clarified that it's always three items. This is probably a bit overkill for the task at hand.
You can create a new array with 1's and use array_replace to merge it with the original array if you first remove the zero values.
$string = "23:22:0";
$array = explode(":", $string);
$fill = array_fill(0,count($array), 1); //create new array [1,1,1]
$array= array_filter($array); // remove zero values
$array= array_replace($fill,$array); // "merge" the arrays
var_dump($array);
Output:
array(3) {
[0]=>
string(2) "23"
[1]=>
string(2) "22"
[2]=>
int(1)
}
https://3v4l.org/thpfU
With three items in mind you can make the code look better with a loop.
It will perform about the same I believe.
foreach($array as &$val){
if(!$val) $val=1;
}

get the sum and difference of two associate array in php

I have 2 arrays.
arr1 =array('cat'=>5,'dog'=>2);
arr2 = array('cat'=>1,'dog'=>2);
I need to get the sum of 2 arrays and the difference of these arrays.
arr3 = array(cat =>6,dog =>4);
arr4 = array(cat =>4 ,dog =>0);
I tried USING array_merge,array_diff,array_combine
But nothing gives me what i need.
plz help
Assuming we have the same number of like keys in both arrays we can iterate through one or the other and find and work with the corresponding values belonging to the other identified by the same named keys.
<?php
$a1 = array('cat'=>5,'dog'=>2);
$a2 = array('cat'=>1,'dog'=>2);
foreach($a1 as $k => $v)
{
$add[$k] = $v + $a2[$k];
$sub[$k] = $v - $a2[$k];
}
var_dump($add, $sub);
Output:
array(2) {
["cat"]=>
int(6)
["dog"]=>
int(4)
}
array(2) {
["cat"]=>
int(4)
["dog"]=>
int(0)
}
You could always resolve the first problem with array_sum.
Second is more interesting, I'd solve it with an array_map. See it in action here
$subtracted = array_map(function ($x, $y) {
return $x - $y;
}, $arr1, $arr2);
$result = array_combine(array_keys($arr1), $subtracted);
Note that you can also solve the first problem by replacing - with + in the above example.
Also note that array_map tends to be generally more readable.
Simple foreach can do it, below example if some key is missing and just getting difference not in -ve Negative sign, the difference would be 4 not -4 for 1 cat - 5 cat
<?php
$arr1 =array('cat'=>5,'dog'=>2);
$arr2 = array('cat'=>1,'dog'=>2);
$sum= [];
$sub= [];
foreach(array_merge($arr1,$arr2) as $k=>$v){
$a1 = $arr1[$k] ?? 0;
$a2 = $arr2[$k] ?? 0;
$sum[$k] = $a1 + $a2;
$sub[$k] = abs($a1 - $a2);
}
print_r($sum);
print_r($sub);
?>
Live Demo
With simple foreach loop
If some data exist only in single array

PHP array_merge empty values always less prioritar

My goal is to merge 2 different arrays.
I have table "a" & "b".
Data from table "a" are more prioritar.
PROBLEM: if a key from "a" contains an empty value, I would like to take the one from table "b".
Here is my code:
<?php
$a = array('key1'=> "key1 from prioritar", 'my_problem'=> "");
$b = array('key1'=> "key1 from LESS prioritar", 'key2'=>"key2 from LESS prioritar", 'my_problem'=> "I REACHED MY GOAL!");
$merge = array_merge($b, $a);
var_dump($merge);
Is there a way to do this in one function without doing something like below?
foreach($b as $key => $value)
{
if(!array_key_exists($key, $a) || empty($a[$key]) ) {
$a[$key] = $value;
}
}
You can use array_replace and array_filter
$mergedArray = array_replace($b, array_filter($a));
The result would be:
array(3) {
["key1"]=>
string(19) "key1 from prioritar"
["key2"]=>
string(24) "key2 from LESS prioritar"
["my_problem"]=>
string(18) "I REACHED MY GOAL!"
}
Just array_filter() $a which will remove any item with '' value.
$merge = array_merge($b, array_filter($a));

php: Keep only max values in an array?

Given a simple array like
$testarr = array("Donna"=>3, "Luke" => 4, "Pete" =>4, "Lola" => 1);
How can I keep only the max values?
I am aware I could do a
max($testarr);
and then loop through the array removing values that differ, but maybe sg like array_filter, or a more elegant one liner solution is available.
Here is your one-liner using array_filter:
<?php
$testarr = array("Donna"=>3, "Luke" => 4, "Pete" =>4, "Lola" => 1);
$max = max($testarr);
$only_max = array_filter($testarr, function($item) use($max){ return $item == $max; });
var_dump( $only_max );
Output:
array(2) {
["Luke"]=>
int(4)
["Pete"]=>
int(4)
}
Note that the closure function is referencing $max. As suggested by #devon, referencing the original array would make the code shorter & general, in exchange for calculation efficiency.
$only_max = array_filter($testarr,
function($item) use($testarr){
return $item == max($testarr);
});
This will get you where you need to go:
<?php
function less_than_max($element)
{
// returns whether the input element is less than max
return($element < 10);
}
$array1 = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);
$array2 = array("a" => 6, "b"=>7, "c"=>8, "d"=>9, "e"=>10, "f"=>11, "g"=>12);
$max = 3;
echo "Max:\n";
print_r(array_filter($array1, "less_than_max"));
echo "Max:\n";
print_r(array_filter($array2, "less_than_max"));
?>

Most efficient way to get keys,values between two keys of an Associative array

i have an array
$var = array("one"=>"one","two"=>"two","three"=>"three","four"=>"four");
if i passed keys one,three i want to get values one , two ,three with keys .
now i am doing is
$new_array = array_diff(array_slice($var,$key1),array_slice($var,$key2));
$new_array[$key1] = $var[$key1];
$new_array[$key2] = $var[$key2];
is there any efficient way , please help .
You pass in a key $from and a key $to. To have something from - to working, you need to know the order as well. You get the order of keys with array_keys:
$keys = array_flip(array_keys($array));
Now you can locate both the offset of $from and $to keys:
array_slice($array, $keys[$from], $keys[$to] - $keys[$from] + 1);
Compile as a full example:
<?php
/**
* Most efficient way to get keys,values between two keys of an Associative array
* #link http://stackoverflow.com/q/11358192/367456
*/
$array = array("one" => "one", "two" => "two", "three" => "three", "four" => "four");
$slice = function($from, $to) use ($array)
{
$keys = array_flip(array_keys($array));
if (isset($keys[$from]) and isset($keys[$to])) {
return array_slice($array, $keys[$from], $keys[$to] - $keys[$from] + 1);
}
throw new InvalidArgumentException('Invalid from and/or to key.');
};
var_dump($slice('one', 'three'));
Output:
array(3) {
["one"]=>
string(3) "one"
["two"]=>
string(3) "two"
["three"]=>
string(5) "three"
}
Assuming your input array has contiguous keys, why not just:
$newArray = array_slice($array, $key1, $key2 + 1);
EDIT
Oh wait, that will only work when $key1 = 0, try this instead:
$newArray = array_slice($array, $key1, ($key2 - $key1) + 1);
This still requires that $key1 < $key2, but from what you say I imagine it always will be.
ANOTHER EDIT
In order to accomplish this without looping the array (with would of course be the easiest way) you need to convert the string keys to numerics so they can be used with array_slice(). This works:
$var = array("one"=>"one","two"=>"two","three"=>"three","four"=>"four");
$key1 = 'one';
$key2 = 'three';
$keys = array_keys($var);
$key1index = array_search($key1, $keys);
$key2index = array_search($key2, $keys);
$newArray = array_slice($var, $key1index, ($key2index - $key1index) + 1, TRUE);
print_r($newArray);

Categories