PHP: Count the appearance of particular value in array - php

I am wondering if I could explain this.
I have a multidimensional array , I would like to get the count of particular value appearing in that array
Below I am showing the snippet of array . I am just checking with the profile_type .
So I am trying to display the count of profile_type in the array
EDIT
Sorry I've forgot mention something, not something its the main thing , I need the count of profile_type==p
Array
(
[0] => Array
(
[Driver] => Array
(
[id] => 4
[profile_type] => p
[birthyear] => 1978
[is_elite] => 0
)
)
[1] => Array
(
[Driver] => Array
(
[id] => 4
[profile_type] => d
[birthyear] => 1972
[is_elite] => 1
)
)
)

Easy solution with RecursiveArrayIterator, so you don't have to care about the dimensions:
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
$counter = 0
foreach ($iterator as $key => $value) {
if ($key == 'profile_type' && $value == 'p') {
$counter++;
}
}
echo $counter;

Something like this might work...
$counts = array();
foreach ($array as $key=>$val) {
foreach ($innerArray as $driver=>$arr) {
$counts[] = $arr['profile_type'];
}
}
$solution = array_count_values($counts);

I'd do something like:
$profile = array();
foreach($array as $elem) {
if (isset($elem['Driver']['profile_type'])) {
$profile[$elem['Driver']['profile_type']]++;
} else {
$profile[$elem['Driver']['profile_type']] = 1;
}
}
print_r($profile);

You may also use array_walk($array,"test") and define a function "test" that checks each item of the array for 'type' and calls recursively array_walk($arrayElement,"test") for items of type 'array' , else checks for the condition. If condition satisfies, increment a count.

Hi You can get count of profuke_type==p from a multi dimensiona array
$arr = array();
$arr[0]['Driver']['id'] = 4;
$arr[0]['Driver']['profile_type'] = 'p';
$arr[0]['Driver']['birthyear'] = 1978;
$arr[0]['Driver']['is_elite'] = 0;
$arr[1]['Driver']['id'] = 4;
$arr[1]['Driver']['profile_type'] = 'd';
$arr[1]['Driver']['birthyear'] = 1972;
$arr[1]['Driver']['is_elite'] = 1;
$arr[2]['profile_type'] = 'p';
$result = 0;
get_count($arr, 'profile_type', 'd' , $result);
echo $result;
function get_count($array, $key, $value , &$result){
if(!is_array($array)){
return;
}
if($array[$key] == $value){
$result++;
}
foreach($array AS $arr){
get_count($arr, $key, $value , $result);
}
}
try this..
thanks

Related

check whether key-value present in any object in array (array of object)

I have array of object as
$a = [{"id":"20","invoice_id":"123"},{"id":"21","invoice_id":"123"},{"id":"22","invoice_id":"125"},{"id":"23","invoice_id":"125"},{"id":"24","invoice_id":"123"}];
here i want to create new array of abject in which duplicate object will not be there (invoice_id) as new array will be having first object of same invoice_id. i was doing like this.
foreach ($a as $key => $value) {
if(isset($new)) {
foreach ($new as $k => $val) {
if($val->id != $value->id) {
$new[] = $value;
}
}
}else{
$new[] = $value;
}
}
my new array will be like
$new = [{"id":"20","invoice_id":"123"},{"id":"22","invoice_id":"125"}]
but it is not giving desired output . What should be done ?
Since you tagged this as Laravel question use collections.
Less code (one line!) and performance hit is non-existent.
$a = json_decode('[{"id":"20","invoice_id":"123"},{"id":"21","invoice_id":"123"},{"id":"22","invoice_id":"125"},{"id":"23","invoice_id":"125"},{"id":"24","invoice_id":"123"}]');
$result = collect($a)->groupBy('invoice_id');
After OP edited question:
$result = collect($a)->unique('invoice_id')->values()->toArray();
results in:
=> [
{#826
+"id": "20",
+"invoice_id": "123",
},
{#824
+"id": "22",
+"invoice_id": "125",
},
]
or using ->toJson() instead of ->toArray()
"[{"id":"20","invoice_id":"123"},{"id":"22","invoice_id":"125"}]"
Please try the below code with simple logic,
$temp = $new = array();
$b = json_decode($a, true);
foreach ($b as $key => $val) {
if(!in_array($val['invoice_id'], $temp)) {
$temp[$val['id']] = $val['invoice_id'];
$new[] = array('id' => $val['id'], 'invoice_id' => $val['invoice_id']);
}
}
print_r($new);
I am just creating a temp array to store only the unique invoice_id to compare in a loop.
It gives the below result,
Array
(
[0] => Array
(
[id] => 20
[invoice_id] => 123
)
[1] => Array
(
[id] => 22
[invoice_id] => 125
)
)
$result = [];
foreach ($a as $data) {
$result[$data->id] = $data;
}
var_dump(array_values($results));
Try this
$a = json_decode($a);
$invoiceid = [];
$unique = [];
foreach ($a as $key => $value) {
if(!in_array($value->invoice_id,$invoiceid)) {
$invoiceid[] = $value->invoice_id;
$unique[] = $value;
}
}
echo $a = json_encode($unique);

check exist all value every single key in array?

i have an $arrays array like this :
Array
(
[0] => Array
(
[0] => VUM
[1] => UA0885
)
[1] => Array
(
[0] => VUA
[1] => UA0885
)
)
i want to check if input value exist (VUA & UA0885), than not add it to this array.
Ex:
(VUA & UA0885) => not add
(VUB & UA0885) => add
(VUA & UA0886) => add
here is my code:
foreach($arrays as $array){
if($array[0] != $_REQUEST['tourcode'] || $array[1] != $_REQUEST['promocode']){
$arrays[] = array($_REQUEST['tourcode'],$_REQUEST['promocode']);
}
}
Tried use in_array too but it still add a duplicate to $arrays
You can iterate the array, check if the same values are found, and if not push the new values:
$tour = $_REQUEST['tourcode'];
$promo = $_REQUEST['promocode'];
$new = true; //default to true
foreach($arrays as $el){
if($el[0].'-'.$el[1] == $tour. '-' .$promo]){
$new=false;
break; //no need to continue
}
}
if($new) $arrays[]=[$tour,$promo];
foreach($arrays as $key => $array) {
if($array[0] == $_REQUEST['tourcode'] && $array[1] == $_REQUEST['promocode']) {
unset($arrays[$key]);
}
}
To check if there is an entry with tourcode AND promocode already in the array you can use something close to what you had:
function codeInArray($array, $tourcode, $promocode) {
foreach ($array as $entry) {
// check if we have an entry that has the same tour and promo code
if ($entry[0] == $tourcode && $entry[1] == $promocode) {
return true;
}
}
return false;
}
Then you can use it like this:
// run the function and see if its not in the array already
if (!codeInArray($arrays, $_GET['tourcode'], $_GET['promocode'])) {
// add the new entry to `$arrays`
$arrays[] = [
$_GET['tourcode'],
$_GET['promocode'],
];
}
As I understood changing your statement for !in_array might be the solution:
if (!in_array(array($_REQUEST['tourcode'],$_REQUEST['promocode']),$array))
<?php
$array = array(
0=>array(
0=>'VUM',
1=>'UA0885'
),
1=>array(
0=>'VUA',
1=>'UA0885'
)
);
$tour_code = trim($_REQUEST['tourcode']);
$promo_code = trim($_REQUEST['promocode']);
$filterarray = array();
$counter = 0;
foreach($array as $subarray){
foreach($subarray as $key => $value){
if(!in_array($tour_code , $subarray) || !in_array($promo_code , $subarray)){
$filterarray[$counter][] = $value;
}
}
$counter++;
}
print_r($filterarray);
?>

PHP update quantity in multidimensional array

My array looks like the following:
Array
(
[0] => Array
(
[index] => 0
[quantity] => 1
[0] => Array
(
[id_product] => 20
[title] => Oranges
)
)
[1] => Array
(
[index] => 1
[quantity] => 1
[0] => Array
(
[id_product] => 24
[title] => Bananas
)
)
)
To make this array, this is my code:
$i = 0;
$content = array();
if(isset($_SESSION['cart'])){
foreach($_SESSION['cart'] as $result){
foreach($result as $item){
$values = $product->getById($item['id']);
if($values != null){ // which means it has product
/*
Checks if the array already contains that ID
this avoids duplicated products
*/
if(main::search_multidimensional($content, "id_product", $item['id_product']) == null){
$content[] = array("index" => $i, "quantity" => 1, $values);
$i++;
}else{ /*
in case it does have already the id_product in the array
I should update the "quantity" according to the "index".
*/
}
}
}
}
}
return $content;
My problem is after the }else{. I've been trying some codes without any success. I have to update the quantity according to the index. Although if you guys think there's a better alternative please let me know.
Edit: Since most of the people is worried about the search_multidimensional and it might be my solution, here's the function:
public function search_multidimensional($array, $key, $value){
$results = array();
if (is_array($array)) {
if (isset($array[$key]) && $array[$key] == $value) {
$results[] = $array;
}
foreach ($array as $subarray) {
$results = array_merge($results, self::search_multidimensional($subarray, $key, $value));
}
}
return $results;
}
EDIT 2:
In that case, would this help? (Since your search_multidimensional only returns a true or false)
$i = 0;
$content = array();
if(isset($_SESSION['cart'])){
foreach($_SESSION['cart'] as $result){
foreach($result as $item){
$values = $product->getById($item['id']);
if($values != null) { // which means it has product
/*
Checks if the array already contains that ID
this avoids duplicated products
*/
$product_exists = false;
foreach($content as &$cItem) {
if($cItem['values']['id_product'] == $item['id_product']) {
$cItem['values']['quantity']++; // Increments the quantity by 1
$product_exists = true;
break;
}
}
// If the product does not exist in $content, add it in.
if(!$product_exists)
$content[] = array("index" => $i, "quantity" => 1, "values" => $values);
$i++;
}
}
}
}
(Edited again to give an array key to $values)
OLD ANSWER:
Since you are recreating the cart array in $content, you could just do this in your else:
$content[] = array("index" => $i, "quantity" => $result['quantity'] + 1, $values);
Such that it would show like this:
$i = 0;
$content = array();
if(isset($_SESSION['cart'])){
foreach($_SESSION['cart'] as $result){
foreach($result as $item){
$values = $product->getById($item['id']);
if($values != null){ // which means it has product
/*
Checks if the array already contains that ID
this avoids duplicated products
*/
if(main::search_multidimensional($content, "id_product", $item['id_product']) == null)
$content[] = array("index" => $i, "quantity" => 1, $values);
else
$content[] = array("index" => $i, "quantity" => $result['quantity'] + 1, $values); // Retrieve current quantity and adds 1
$i++;
}
}
}
}
(I'm assuming you are only increasing the quantity by 1)
Solved.
All I had to do was to forget the $i variable, since it wasn't actually doing something necessary. Since I have id_product, which is unique I need to work with it.
if($values != null){ // Only if it has results
// checks if array already contains or not the product ID
// if does not have, it will add
if(global_::search_multidimensional($content, "id_product", $item['id_product']) == null){
$content[] = array("index" => $item['id_product'], "quantity" => 1, $values);
// index is now the id of the product
}else{
// otherwise, loop all the elements and add +1
foreach($content as $key => $result){
if($item['id_product'] == $content[$key]['index']){
$content[$key]['quantity']++;
}
}
}
}
As your $content array has fixed structure (fixed number of levels) you don't need to use recursive function. Your search_multidimensional function could be much simpler. And it should return index of found element (if any) in the array:
function search_multidimensional($array, $key, $value) {
foreach ($array as $i => $el) {
foreach ($el as $j => $v) {
if (is_int($j) && isset($v[$key]) && $v[$key] == $value) return $i;
}
}
return false;
}
So the snippet building $content should be changed like this:
...
if (($index = search_multidimensional($content, "id_product", $item['id_product'])) === false) {
$content[] = array("index" => $i, "quantity" => 1, $values); $i++;
}
else {
$content[$index]['quantity']++;
}

How to find object in php array and delete it?

Here is print_r output of my array:
Array
(
[0] => stdClass Object
(
[itemId] => 560639000019
[name] => Item no1
[code] => 00001
[qty] => 5
[id] => 2
)
[1] => stdClass Object
(
[itemId] => 470639763471
[name] => Second item
[code] => 76347
[qty] => 9
[id] => 4
)
[2] => stdClass Object
(
[itemId] => 56939399632
[name] => Item no 3
[code] => 39963
[qty] => 6
[id] => 7
)
)
How can I find index of object with [id] => 4 in order to remove it from array?
$found = false;
foreach($values as $key => $value) {
if ($value->id == 4) {
$found = true;
break;
}
}
if ($found) unset($values[$key]);
This is considered to be faster then any other solution since we only iterate the array to until we find the object we want to remove.
Note: You should not remove an element of an array while iterating so we do it afterwards here.
foreach($parentObj AS $key=>$element){
if ($element->id == THE_ID_YOU_ARE_LOOKING_FOR){
echo "Gottcha! The index is - ". $key;
}
}
$parentObj is obviously your root array - the one that holds all the others.
We use the foreach loop to iterate over each item and then test it's id property against what ever value you desire. Once we have that - the $key that we are on is the index you are looking for.
use array_search:
$a = new stdClass;
$b = new stdClass;
$a->id = 1;
$b->id = 2;
$arr = array($a, $b);
$index = array_search($b, $arr);
echo $index;
// prints out 1
try this
foreach($array AS $key=>$object){
if($object['id'] == 4){
$key_in_array = $key;
}
}
// chop it from the original array
array_slice($array, $key_in_array, 1);
Another way to achieve the result is to use array_filter.
$array = array(
(object)array('id' => 5),
(object)array('id' => 4),
(object)array('id' => 3)
);
$array = array_filter($array, function($item) {
return $item->id != 4;
});
print_r($array);
Here's my solution. Given, it is a bit hackish, but it will get the job done.
search(array $items, mixed $id[, &$key]);
Returns the item that was found by $id. If you add the variable $key it will give you the key of the item found.
function search($items, $id, &$key = null) {
foreach( $items as $item ) {
if( $item->id == $id ) {
$key = key($item);
return $item;
break;
}
}
return null;
}
Usage
$item = search($items, 4, $key);
unset($items[$key]);
Note: This could be modified to allow a custom key and return multiple items that share the same value.
I've created an example so you can see it in action.
A funny alternative
$getIdUnset = function($id) use ($myArray)
{
foreach($myArray as $key => $obj) {
if ($obj->id == $id) {
return $key;
}
}
return false;
};
if ($unset = $getIdUnset(4)) {
unset($myArray[$unset]);
}
Currently php does not have any supported function for this yet.
So refer to Java's Vector, or jQuery's $.inArray(), it would simply be:
public function indexOf($object, array $elementData) {
$elementCount = count($elementData);
for ($i = 0 ; $i < $elementCount ; $i++){
if ($object == $elementData[$i]) {
return $i;
}
}
return -1;
}
You can save this function as a core function for later.
In my case, this my array as $array
I was confused about this problem of my project, but some answer here helped me.
array(3) {
[0]=> float(-0.12459619130796)
[1]=> float(-0.64018439966448)
[2]=> float(0)
}
Then use if condition to stop looping
foreach($array as $key => $val){
if($key == 0){ //the key is 0
echo $key; //find the key
echo $val; //get the value
}
}
I know, after so many years this could be a useless answer, but why not?
This is my personal implementation of a possible index_of using the same code as other answers but let the programmer to choose when and how the check will be done, supporting also complex checks.
if (!function_exists('index_of'))
{
/**
* #param iterable $haystack
* #param callable $callback
* #param mixed|null &$item
* #return false|int|string
*/
function index_of($haystack, $callback, &$item = null)
{
foreach($haystack as $_key => $_item) {
if ($callback($_item, $_key) === true) {
$item = $_item;
return $_key;
}
}
return false;
}
}
foreach( $arr as $k=>&$a) {
if( $a['id'] == 4 )
unset($arr[$k]);
}

Sort an associative array in php with multiple condition

Consider following array
$details = array(
array('lname'=>'A', 'fname'=>'P','membkey'=>700,'head'=>'y'),
array('lname'=>'B', 'fname'=>'Q','membkey'=>540,'head'=>'n'),
array('lname'=>'C', 'fname'=>'R','membkey'=>700,'head'=>'n'),
array('lname'=>'D', 'fname'=>'S','membkey'=>540,'head'=>'y'),
array('lname'=>'E', 'fname'=>'T','membkey'=>700,'head'=>'n')
);
Here I would like to sort with head and membkey. Top element of same membkey element should have 'head=y' and echoed as,
$details = array(
array('lname'=>'A', 'fname'=>'P','membkey'=>700,'head'=>'y'),
array('lname'=>'E', 'fname'=>'T','membkey'=>700,'head'=>'n'),
array('lname'=>'C', 'fname'=>'R','membkey'=>700,'head'=>'n'),
array('lname'=>'D', 'fname'=>'S','membkey'=>540,'head'=>'y'),
array('lname'=>'B', 'fname'=>'Q','membkey'=>540,'head'=>'n')
);
I tried it as follows
function orderbymemberKey( $a, $b ){
if ( $a[membkey] == $b[membkey] )
return 0;
return($a[membkey] < $b[membkey] )? -1 :1;
}
usort( $details, orderbymemberKey );
and it successfully order by membkey.
Any suggestions please.
You're half way there (though you were sorting backwards for membkey based on your example):
function order_by_member_key($a, $b)
{
if ($a['membkey'] == $b['membkey'])
{
// membkey is the same, sort by head
if ($a['head'] == $b['head']) return 0;
return $a['head'] == 'y' ? -1 : 1;
}
// sort the higher membkey first:
return $a['membkey'] < $b['membkey'] ? 1 : -1;
}
usort($details, "order_by_member_key");
Is this array being pulled from a database? Because, if so, you should be able to make use of ORDER BY clauses to clean it up outside of php.
<?php
$membkey = array();
$head = array();
foreach ($details as $key => $row) {
$membkey[$key] = $row['membkey'];
$head[$key] = $row['head'];
}
array_multisort($membkey, SORT_DESC, $head, SORT_DESC, $details);
print_r($details);
Or, an even more generic solution:
function sort_by($array) {
$arguments = func_get_args();
$array = array_pop($arguments);
$variables = array();
foreach ($arguments as $index => $key) {
$variables[] = '$arguments['.$index.']';
if ($index % 2 == 0) {
$arguments[$index] = array();
foreach ($array as $row) $arguments[$index][] = $row[$key];
}
}
// call_user_func_array will not work in this case
eval('array_multisort('.implode(', ', $variables).', $array);');
return $array;
}
print_r(sort_by('membkey', SORT_DESC, 'head', SORT_DESC, $details));
Ugly but someone wrote a function on php.net:
http://php.net/manual/en/function.sort.php
<?php
$array[0]['name'] = 'Chris';
$array[0]['phone'] = '3971095';
$array[0]['year'] = '1978';
$array[0]['address'] = 'Street 1';
$array[1]['name'] = 'Breanne';
$array[1]['phone'] = '3766350';
$array[1]['year'] = '1990';
$array[1]['address'] = 'Street 2';
$array[2]['name'] = 'Dusty';
$array[2]['phone'] = '1541120';
$array[2]['year'] = '1982';
$array[2]['address'] = 'Street 3';
function multisort($array, $sort_by, $key1, $key2=NULL, $key3=NULL, $key4=NULL, $key5=NULL, $key6=NULL){
// sort by ?
foreach ($array as $pos => $val)
$tmp_array[$pos] = $val[$sort_by];
asort($tmp_array);
// display however you want
foreach ($tmp_array as $pos => $val){
$return_array[$pos][$sort_by] = $array[$pos][$sort_by];
$return_array[$pos][$key1] = $array[$pos][$key1];
if (isset($key2)){
$return_array[$pos][$key2] = $array[$pos][$key2];
}
if (isset($key3)){
$return_array[$pos][$key3] = $array[$pos][$key3];
}
if (isset($key4)){
$return_array[$pos][$key4] = $array[$pos][$key4];
}
if (isset($key5)){
$return_array[$pos][$key5] = $array[$pos][$key5];
}
if (isset($key6)){
$return_array[$pos][$key6] = $array[$pos][$key6];
}
}
return $return_array;
}
//usage (only enter the keys you want sorted):
$sorted = multisort($array,'year','name','phone','address');
print_r($sorted);
//output:
Array ( [0] => Array ( [year] => 1978 [name] => Chris [phone] => 3971095 [address] => Street 1 ) [2] => Array ( [year] => 1982 [name] => Dusty [phone] => 1541120 [address] => Street 3 ) [1] => Array ( [year] => 1990 [name] => Breanne [phone] => 3766350 [address] => Street 2 ) )

Categories