count occurrences of values in an associative array in php - php

Please help me on how to count the occurrences of value in this associative array.
<?php
$employees = array(
1 => array(
'name' => 'Jason Alipala',
'employee_id' => 'G1001-05',
'position' => 1
),
2 => array(
'name' => 'Bryann Revina',
'employee_id' => 'G1009-03',
'position' => 2
),
3 => array(
'name' => 'Jeniel Mangahis',
'employee_id' => 'G1009-04',
'position' => 2
),
4 => array(
'name' => 'Arjay Bussala',
'employee_id' => 'G1009-05',
'position' => 3
),
5 => array(
'name' => 'Ronnel Ines',
'employee_id' => 'G1002-06',
'position' => 3
)
);
?>
This is my code from fake_db.php which I include_once in the index.php. I want to count the occurrences of the same value of 'position'.. e.g. 1 = 1, 2 = 2, 3 = 2
in addition, there is another array named $positions...
$positions = array(
1 => 'TL',
2 => 'Programmer',
3 => 'Converter');
this array is where i compare the 'position' from the $employees array.
any help is appreciated, thank you!

Combination of array_count_values & array_column (PHP 5 >= 5.5.0, PHP 7) should work -
$counts = array_count_values(
array_column($employees, 'position')
);
Output
array(3) {
[1]=>
int(1)
[2]=>
int(2)
[3]=>
int(2)
}
Update
$final = array_filter($counts, function($a) {
return $a >= 2;
});
Output
array(2) {
[2]=>
int(2)
[3]=>
int(2)
}
Demo

array_column — Return the values from a single column of array. array_count_values — Counts all the values of an array.
$positions = array_column($employees, 'position');
print_r(array_count_values($positions));
Output
Array
(
[1] => 1
[2] => 2
[3] => 2
)

Nested loop will do the job. Take an array, keep the key as the actual value and the value in the key as COUNTER of that key.
if the key exists in array that means it has the value just increment else assign 1 to initialize the key with value 1.
e.g. 1=>counter of 1 (occurrences)
$arrayCounter=0;
foreach($employees as $value){
foreach($value as $data){
$position = $data['position'];
if(array_key_exists($position,$arrayCounter)){
$arrayCounter[$position] = arrayCounter[$position]++;
}
else{
$arrayCounter[$position] = 1;
}
}

It is pretty simple. The array $employees is the array you have supplied. You can use this code:
$data = array();
foreach($employees as $employee) {
if(isset($data[$employee['position']])) {
$data[$employee['position']]++;
} else {
$data[$employee['position']] = 1;
}
}
echo "<pre>";
print_r($data);
echo "</pre>";
This gives the output:
Array
(
[1] => 1
[2] => 2
[3] => 2
)

You can use array_count_value() pre-define php function to get your aim.
you can see result here

$total = 0;
foreach($employees as $eNum => $value){
if($aEmployees[$eNum]['position'] == $key){
$total++;
}
}
echo $total;
These codes are inside a function that is called on every iteration of a foreach loop(another array named '$positions')..
$key is a variable that contains value from that foreach loop (the '$positions' array).. this is what I've done, and it works for me. But i don't know if this is the proper way?

Related

Compare multidimensional array with each other and some array field with external variable

I have an array like below. I need to compare with each other and return the matching array on the first index and followed by other.
How can we compare whole array each other based on id and scid with $scid?
$scid = 307;
$array = array(
0 =>
array(
'id' => '485',
'scid' => 306
),
1 =>
array(
'id' => '484',
'scid' => null
),
2 =>
array(
'id' => '486',
'scid' => 305
),
3 =>
array(
'id' => '485',
'scid' => 307
),
4 =>
array(
'id' => '485',
'scid' => 309
),
5 =>
array(
'id' => '485',
'scid' => 329
),
);
The result array should be like
array(3) {
[485]=> array(2) { ["id"]=> string(3) "485" ["scid"]=> int(307) }
[484]=> array(2) { ["id"]=> string(3) "484" ["scid"]=> NULL }
[486]=> array(2) { ["id"]=> string(3) "486" ["scid"]=> int(305) }
}
If array has duplicate id on which scid is not matching then we can pick any id value.
Note :The matching sub array should always be the first index of resulting array.An amount will always be unique and might contain null as well in array.
You want something like this?
$result = [];
foreach ($array as $item) {
$result[$item['id']] = ['id' => $item['id'], 'scid' => $item['scid']];
}
var_dump($result);
Try this,
$temp = [];
foreach($array as $k => $v){
$temp[$v['id']][] = $v;
}
Give it a try, this will work.

How to check if duplicate values of some indexes exist in multi dimensional array or not?

My problem is i have a multidimensional array posting from form to php, now i want to checking if duplicate values of some indexes exist in multi dimensional array or not?
e.g:
$data=Array
(
0 => Array
(
uid => '100',
name => 'Sandra Shush',
type => 'abc'
),
1 => Array
(
uid => '101',
name => 'Sandra Shushtext',
type => 'xyz'
),
2 => Array
(
uid => '100',
name => 'Sandra Shush',
type => 'abc'
)
);
here name and type of index 1 and 2 are same, so how can i check it?
I am familiar with
$key = array_search('abc', array_column($data, 'type'));
but it is for duplication of single column value in multi rows, in my situation if multi column of same rows same with multi column of any other row then record will be consider as duplicate.
Any help should be appreciated, Thanks in advance.
You can try using array_reduce by creating a key using your desired item keys:
$result = array_reduce($data, function ($carry, $item) {
$key = $item['uid'] . $item['type'];
$item['is_duplicate'] = isset($carry[$key]);
if ($item['is_duplicate']) {
$carry[] = $item;
} else {
$carry[$key] = $item;
}
return $carry;
}, []);
var_dump($result);
The easiest way, well at least the one I would use is to encode your arrays into md5 (or any other kind) string and compare those values. I think it is the most efficient in your case.
Example:
<?php
function arrayToString($array) {
$str = '';
if ( !is_array($array) )
return $str;
foreach ( $array as $key => $val ) {
$str .= $key . ':' . $val;
}
return $str;
}
$data=Array
(
0 => Array
(
'uid' => '100',
'name' => 'Sandra Shush',
'type' => 'abc'
),
1 => Array
(
'uid' => '100',
'name' => 'Sandra Shush',
'type' => 'xyz'
),
2 => Array
(
'uid' => '100',
'name' => 'Sandra Shush',
'type' => 'abc'
)
);
$temp = array();
foreach ( $data as $d ) {
array_push($temp, md5(arrayToString($d)));
}
$unique = array_unique($temp);
var_dump($unique); // prints unique array
This is a very fast designed approach and will find duplicates. Note that duplicates are elements which have the same value for the same key. So if any of uid, name or type match, they will be treated as duplicates. Therefore I adjust the third array element, because all elements in your array share the same values.
$data = [
....
2 =>
[
'uid' => '200',
'name' => 'Mandra Shush',
'type' => 'abcx'
]
];
$duplicates = [];
$valuesToCompare = ["uid", "name", "type"];
function equals($value, $toCompare, $keysToCompare)
{
foreach ($keysToCompare as $compareKey) {
if ($value[$compareKey] === $toCompare[$compareKey]) {
return true;
}
}
return false;
}
foreach ($data as $index => $element) {
foreach ($data as $indexInner => $elementToCompare) {
if ($index !== $indexInner) {
if (equals($element, $elementToCompare, $valuesToCompare)) {
$duplicates[] = [$index => $indexInner];
}
}
}
}
var_dump($duplicates);
This will output the following, which indicates we found 2 duplicates. Where element 0 is duplicate of 1, and 1 is duplicate of 0.
array (size=2)
0 =>
array (size=1)
0 => int 1
1 =>
array (size=1)
1 => int 0
I achieved above scenario like this:
Dont know which one is best mine or other's who posted answers.
foreach($data as $key => $row)
{
$combinedarr[] = array("name"=>$row["name"],"type"=>$row["type"]);
}
//chck if same facilitiy is being visit on same date twice
$countcomb = count($combinedarr);
$uniquearr = array_unique($combinedarr, SORT_REGULAR);
if($countcomb==count($uniquearr)){
}else{
//yes duplicate exists
};
Thanks again for those who answered.

Multiple values from one loop php

If I have this array -
$data_item['actor_id'] = $this->input->post('actor_id');
$data_item['item_number'] = $this->input->post('item_number');
Which gives me this array -
Array (
[actor_id] => Array (
[0] => 162652153
[1] => 162652154
)
[item_number] => Array (
[0] => 3
[1] => 6
)
)
I need to get my data into this format -
$data = array(
array(
'actor_id' => '3342' ,
'item_number' => '57567'
),
array(
'actor_id' => '876' ,
'item_number' => '94'
)
);
I have tried various ways of looping through it but I can't seem to get it. Such as two seperate loops like this -
foreach($data_item['actor_id'] as $key => $value){
$thevalue[] = array('actor_id' => $value
);
}
But it is wrong format. Any tips please?
What about:
$d = [
'actor_id' => [
1,
2,
],
'item_number' => [
3,
4,
],
];
$res = [];
foreach ( $d as $key => $data ) {
foreach ( $data as $index => $value ) {
$res [ $index ] [$key] = $value;
}
}
I'll generate:
array(2) {
[0]=>
array(2) {
["actor_id"]=>
int(1)
["item_number"]=>
int(3)
}
[1]=>
array(2) {
["actor_id"]=>
int(2)
["item_number"]=>
int(4)
}
}
HTH
you can make use of the actor_id keys to flatten your data as desired:
$data = array(); // your new array
foreach($data_item['actor_id'] as $key => $value) {
// make sure we have an array for this key and add actor id
if (!isset($data[$key])) $data[$key] = array();
$data[$key]['actor_id'] = $value;
// now check if we have an item number for this key and add it
if (isset($data_item['item_number'][$key]))
$data[$key]['item_number'] = $data_item['item_number'][$key];
}
print_r($data);
The result should print out just as you wanted it. Sorry for not having tested the code my self, just typed it out of my head missing time and interpreter right now :)

Matching an array value by key in PHP

I have an array of items:
array(
[0] => array(
'item_no' => 1
'item_name' => 'foo
)
[1] => array(
'item_no' => 2
'item_name' => 'bar'
)
) etc. etc.
I am getting another array from a third party source and need to remove items that are not in my first array.
array(
[0] => array(
'item_no' => 1
)
[1] => array(
'item_no' => 100
) # should be removed as not in 1st array
How would I search the first array using each item in the second array like (in pseudo code):
if 'item_no' == x is in 1st array continue else remove it from 2nd array.
// Returns the item_no of an element
function get_item_no($arr) { return $arr['item_no']; }
// Arrays of the form "item_no => position in the array"
$myKeys = array_flip(array_map('get_item_no', $myArray));
$theirKeys = array_flip(array_map('get_item_no', $theirArray));
// the part of $theirKeys that has an item_no that's also in $myKeys
$validKeys = array_key_intersect($theirKeys, $myKeys);
// Array of the form "position in the array => item_no"
$validPos = array_flip($validKeys);
// The part of $theirArray that matches the positions in $validPos
$keptData = array_key_intersect($theirArray, $validPos);
// Reindex the remaining values from 0 to count() - 1
return array_values($keptData);
All of this would be easier if, instead of storing the key in the elements, you stored it as the array key (that is, you'd be using arrays of the form "item_no => item_data") :
// That's all there is to it
return array_key_intersect($theirArray, $myArray);
You can also do:
$my_array =array(
0 => array( 'item_no' => 1,'item_name' => 'foo'),
1 => array( 'item_no' => 2,'item_name' => 'bar')
);
$thrid_party_array = array(
0 => array( 'item_no' => 1),
1 => array( 'item_no' => 100),
);
$temp = array(); // create a temp array to hold just the item_no
foreach($my_array as $key => $val) {
$temp[] = $val['item_no'];
}
// now delete those entries which are not in temp array.
foreach($thrid_party_array as $key => $val) {
if(!in_array($val['item_no'],$temp)) {
unset($thrid_party_array[$key]);
}
}
Working link
If your key is not actually a key of your array but a value, you will probably need to do a linear search:
foreach ($itemsToRemove as $itemToRemove) {
foreach ($availableItems as $key => $availableItem) {
if ($itemToRemove['item_no'] === $availableItem['item_no']) {
unset($availableItems[$key]);
}
}
}
It would certainly be easier if item_no is also the key of the array items like:
$availableItems = array(
123 => array(
'item_no' => 123,
'item_name' => 'foo'
),
456 => array(
'item_no' => 456,
'item_name' => 'bar'
)
);
With this you could use a single foreach and delete the items by their keys:
foreach ($itemsToRemove as $itemToRemove) {
unset($availableItems[$itemToRemove['item_no']]);
}
You could use the following to build an mapping of item_no to your actual array keys:
$map = array();
foreach ($availableItems as $key => $availableItem) {
$map[$availableItems['item_no']] = $key;
}
Then you can use the following to use the mapping to delete the corresponding array item:
foreach ($itemsToRemove as $itemToRemove) {
unset($availableItems[$map[$itemToRemove['item_no']]]);
}

Search array keys and return the index of matched key

my array looks like this:
[sx1] => Array
(
[sx1] => Pain in Hand
[sx1L] => Location
[sx1O] => Other Treat
[sx1T] => Type
[sx1R] => Radiation
[sx1A] => Aggrivate Ease
[sx1D] => Duration
[sx1I] => Irit
[sx1P] => Previous Hx
[SX1T_1] => CX
[SX1T_2] => Shld
[SX1T_3] => Trnk
[SX1T_4] => Hip
[SX1T_5] =>
)
I need to be able to search the array by a key, and then return the index of the matched item.
For example, I need to search the array for the key "SX1T_1" and then return the index of that item in the array.
Thanks for any help.
You can use array_search on the array keys (array_keys) to get the numerical index:
$array = array(
'sx1' => 'Pain in Hand',
'sx1L' => 'Location',
'sx1O' => 'Other Treat',
'sx1T' => 'Type',
'sx1R' => 'Radiation',
'sx1A' => 'Aggrivate Ease',
'sx1D' => 'Duration',
'sx1I' => 'Irit',
'sx1P' => 'Previous Hx',
'SX1T_1' => 'CX',
'SX1T_2' => 'Shld',
'SX1T_3' => 'Trnk',
'SX1T_4' => 'Hip',
'SX1T_5' => '',
);
var_dump(array_search('SX1T_1', array_keys($array))); // int(9)
$keys = array_keys($sx1);
$index = array_search('SX1T_1',$keys);
If you don't want to use any functions and need to loop through the array anyway to search or match on a specific condition (especially usefully if your searches become more complicated), then you could use the below principle to go through the array and find the index of $mykey and put it into a variable $myindex. This code assume your index starts at zero, if you want to start at 1, then initialize $index = 1;.
$a = array(
"one" => 1,
"two" => 2,
"three" => 3,
"seventeen" => 17
);
$index = 0;
foreach ($a as $k => $v) {
if ($k == $mykey) {
$myindex=$index
}
$index=$index+1;
}

Categories