PHP search array in array - php

I have array result like this:
Array
(
[0] => stdClass Object
(
[id_global_info] => 78
[name] => rfhd
[body] => dhfdhdf
[contact_author] => mirko
[date_created] => 2012-03-15 16:11:54
[date_expires] => 2012-04-14 16:11:54
[email] =>
[location_id] => 1
[category_id] => 26
[tag] => fhdhfdhfd
[info_type_id] => 4
[user_id] => 3
)
[1] => stdClass Object
(
[id_global_info] => 79
[name] => rfhd
[body] => dhfdhdf
[contact_author] => mirko
[date_created] => 2012-03-15 16:11:56
[date_expires] => 2012-04-14 16:11:56
[email] =>
[location_id] => 1
[category_id] => 26
[tag] => fhdhfdhfd
[info_type_id] => 4
[user_id] => 3
)
[2] => stdClass Object
(
[id_global_info] => 80
[name] => rfhd
[body] => dhfdhdf
[contact_author] => mirko
[date_created] => 2012-03-15 16:11:56
[date_expires] => 2012-04-14 16:11:56
[email] =>
[location_id] => 1
[category_id] => 26
[tag] => fhdhfdhfd
[info_type_id] => 4
[user_id] => 3
)
.
.
.
)
How can I search a multidimensional array and count number of results (for example I want to search for info_type_id with value of 4)?

Use array_filter to filter the array:
function test($arr) {
return $arr["info_type_id"] == 4;
}
echo count(array_filter($yourArray, "test"));

with foreach ?
function searchMyCoolArray($arrays, $key, $search) {
$count = 0;
foreach($arrays as $object) {
if(is_object($object)) {
$object = get_object_vars($object);
}
if(array_key_exists($key, $object) && $object[$key] == $search) $count++;
}
return $count;
}
echo searchMyCoolArray($input, 'info_type_id', 4);

You should try this :
$counter = 0;
$yourArray; // this var is your current array
foreach($yourArray as $object){
if($object->info_type_id == 4){
$counter++;
}
}

Related

array_merge overwrite array with key-value structure

I got this array named $records:
Array
(
[0] => Array
(
[id] => 14
[name] => name1
[publisher] => Dieter
[date] => 2022-07-29
[text] => blablablablablablablablablabblablablablablablablablablablablablablablabla
)
[1] => Array
(
[id] => 16
[name] => name2
[publisher] => Dieter
[date] => 2022-07-28
[text] => awhduawohduawohduawhduawuhdawhduaiwd
)
[2] => Array
(
[id] => 17
[name] => name3
[publisher] => Dieter
[date] => 2022-07-30
[text] => blub
)
[3] => Array
(
[id] => 18
[name] => name4
[publisher] => Dieter
[date] => 2022-07-31
[text] => awdawdw
)
)
and then I want to filter them by their ids($ids=[14,16]):
$articles = array();
foreach ($records as $article) {
if (in_array($article['id'], $ids)) { //alg select only one article
$articles = array_merge($articles, $article);
}
}
return $articles;
and the Output should look like this:
Array
(
[0] => Array
(
[id] => 14
[name] => name1
[publisher] => Dieter
[date] => 2022-07-29
[text] => blablablablablablablablablabblablablablablablablablablablablablablablabla
)
[1] => Array
(
[id] => 16
[name] => name2
[publisher] => Dieter
[date] => 2022-07-28
[text] => awhduawohduawohduawhduawuhdawhduaiwd
)
)
But I got this:
Array
(
[id] => 16
[name] => name2
[publisher] => Dieter
[date] => 2022-07-28
[text] => awhduawohduawohduawhduawuhdawhduaiwd
)
This command doesnt work because I get a diffrent structure:
array_merge_recursiv()
$articles = array();
foreach ($records as $article) {
if (in_array($article['id'], $ids)) { //alg select only one article
$articles[] = $article;
}
}
return $articles;
array_merge is not needed here, you can push a new entry in your table using $articles[].
You can also keep keys of the original table like that :
$articles = array();
foreach ($records as $key => $article) {
if (in_array($article['id'], $ids)) { //alg select only one article
$articles[$key] = $article;
}
}
return $articles;
function array_diff_column_values($rawArray, $searchArray, $columnName = 'id') {
$result = [];
foreach($rawArray as $key => $value) {
if (isset($value[$columnName]) && in_array($value[$columnName], $searchArray)) {
$result[] = $value;
}
}
return $result;
}
echo "<pre>";
print_r(array_diff_column_values($records, [14,16]));
echo "</pre>";

Flatten PHP stdClass object to array maintaining array dimensions

I am working with soap responses that contain nested wrappers and whose child(ren) have nested properties.
I am trying to flatten these response to:
remove the wrappers
flatten the children
maintain the individual children (dimensions)
I am currently working with the following that achieves #1 and #3 however it does not flatten the inner children. Note that $this->response is converted from a stdClass to Array before being flattened.
How can I also flatten down the inner nested child elements?
private function toArray()
{
$this->response = json_decode(json_encode($this->response), true);
return $this;
}
private function flatten($array = null)
{
if (is_null($array)) {
$array = $this->response;
}
if (is_array($array)) {
foreach ($array as $k => $v) {
if (count($v) == 1 && is_array($v)) {
return $this->flatten($v);
}
if (isset($v[0])) {
$this->response = $v;
return $this;
}
unset($this->response);
$this->response[] = $v;
return $this;
}
}
}
...which will transform this:
stdClass Object
(
[ArrayOfDevice] => stdClass Object
(
[Device] => Array
(
[0] => stdClass Object
(
[NamedElement] => stdClass Object
(
[Element] => stdClass Object
(
[ElementType] => DEVICE
[id] => Device1ID
)
[name] => Device1
)
[hostName] => Device1.hostname
[ipAddress] => Device1.ip
[location] => location1
[modelName] =>
[modelNumber] =>
[parentID] => xxxYYY
[serialNumber] => 123456789
)
[1] => stdClass Object
(
[NamedElement] => stdClass Object
(
[Element] => stdClass Object
(
[ElementType] => DEVICE
[id] => Device2ID
)
[name] => Device2
)
[hostName] => Device2.hostname
[ipAddress] => Device2.ip
[location] => location1
[modelName] =>
[modelNumber] =>
[parentID] => xxxYYY
[serialNumber] => 987654321
)
)
)
)
...to this:
Array
(
[0] => Array
(
[NamedElement] => Array
(
[Element] => Array
(
[ElementType] => DEVICE
[id] => Device1ID
)
[name] => Device1
)
[hostName] => Device1.hostname
[ipAddress] => Device1.ip
[location] => location1
[modelName] =>
[modelNumber] =>
[parentID] => xxxYYY
[serialNumber] => 123456789
)
[1] => Array
(
[NamedElement] => Array
(
[Element] => Array
(
[ElementType] => DEVICE
[id] => Device2ID
)
[name] => Device2
)
[hostName] => Device2.hostname
[ipAddress] => Device2.ip
[location] => location1
[modelName] =>
[modelNumber] =>
[parentID] => xxxYYY
[serialNumber] => 987654321
)
)
...but I'd prefer:
Array
(
[0] => Array
(
[ElementType] => DEVICE
[id] => Device1ID
[name] => Device1
[hostName] => Device1.hostname
[ipAddress] => Device1.ip
[location] => location1
[modelName] =>
[modelNumber] =>
[parentID] => xxxYYY
[serialNumber] => 123456789
)
[1] => Array
(
[ElementType] => DEVICE
[id] => Device2ID
[name] => Device2
[hostName] => Device2.hostname
[ipAddress] => Device2.ip
[location] => location1
[modelName] =>
[modelNumber] =>
[parentID] => xxxYYY
[serialNumber] => 987654321
)
)
...and in the case of a single item being returned, this:
stdClass Object
(
[ArrayOfAlarm] => stdClass Object
(
[Alarm] => stdClass Object
(
[Element] => stdClass Object
(
[ElementType] => ALARM
[id] => Alarm1ID
)
[activeTime] =>
[AlarmSeverity] =>
[AlarmState] =>
[description] =>
[deviceID] =>
[recommendedAction] =>
[resolvedTime] =>
[sensorID] =>
)
)
)
...to this:
Array
(
[0] => Array
(
[Element] => Array
(
[ElementType] => ALARM
[id] => Alarm1ID
)
[activeTime] =>
[AlarmSeverity] =>
[AlarmState] =>
[description] =>
[deviceID] =>
[recommendedAction] =>
[resolvedTime] =>
[sensorID] =>
)
)
...but I'd prefer:
Array
(
[0] => Array
(
[ElementType] => ALARM
[id] => Alarm1ID
[activeTime] =>
[AlarmSeverity] =>
[AlarmState] =>
[description] =>
[deviceID] =>
[recommendedAction] =>
[resolvedTime] =>
[sensorID] =>
)
)
You can flatten a single of your items with the following function:
function flatten_item($array)
{
$result = [];
foreach ($array as $k => $v) {
if (is_array($v)) {
$result = array_merge($result, $this->flatten_item($v));
} else {
$result[$k] = $v;
}
}
return $result;
}
When you have an array of results, you can pass this function as the callback to array_map. Only the relevant portion of the code:
if (isset($v[0])) {
$this->response = array_map([$this, 'flatten_item'], $v);
return $this;
}
// Convert single result to an array
$this->response = [$this->flatten_item($v)];
return $this;
Since the response (so far) always has the same structure, you could extract the payload without using recursion, which allows you to also remove the foreach in the flatten function:
function flatten()
{
// Remove outer wrappers [ArrayOfX][X] by extracting the value
$payload = current(current($this->response));
if (isset($payload[0])) {
$this->response = array_map([$this, 'flatten_item'], $payload);
} else {
$this->response = [$this->flatten_item($payload)];
}
return $this;
}
The function found here does just what you want, with a slight modification (commented out concatination of parent keys): https://gist.github.com/kohnmd/11197713#gistcomment-1895523
function flattenWithKeys(array $array, $childPrefix = '.', $root = '', $result = array()) {
foreach($array as $k => $v) {
if(is_array($v) || is_object($v)) $result = flattenWithKeys( (array) $v, $childPrefix, $root . $k . $childPrefix, $result);
else $result[ /*$root .*/ $k ] = $v;
}
return $result;
}
Letting $object equal your provided object, use as follows:
$array = json_decode(json_encode($object), true);
$result =[];
foreach( $array['ArrayOfDevice']['Device'] as $key => $value ){
$result[$key] = flattenWithKeys($value);
}
print_r($result);
Output:
Array
(
[0] => Array
(
[ElementType] => DEVICE
[id] => Device1ID
[hostName] => Device1.hostname
[ipAddress] => Device1.ip
[location] => location1
[modelName] =>
[modelNumber] =>
[parentID] => xxxYYY
[serialNumber] => 123456789
)
[1] => Array
(
[ElementType] => DEVICE
[id] => Device2ID
[name] => Device2
[hostName] => Device2.hostname
[ipAddress] => Device2.ip
[location] => location2
[modelName] =>
[modelNumber] =>
[parentID] => xxxYYY
[serialNumber] => 987654321
)
)
See it run here: http://sandbox.onlinephpfunctions.com/code/851e93389b993a0e44c1e916291dc444f47047d3

cannot find value in array

I can't see where I am wrong with this code so I kindly ask for your help.
I have two arrays:
Array (
[0] => Array (
[description] => Generali di Proprieta'
[idmov] => 34
[mov] => Manutenzioni
[total] => 8000
)
[1] => Array (
[description] => Generali di Proprieta'
[idmov] => 35
[mov] => Assicurazioni
[total] => 6000
)
[2] => Array (
[description] => Generali di Proprieta'
[idmov] => 36
[mov] => Cancelleria Postali
[total] => 1850
)
[3] => Array (
[description] => Generali di Proprieta'
[idmov] => 37
[mov] => Bancarie passive
[total] => 700
)
[4] => Array (
[description] => Generali di Proprieta'
[idmov] => 38
[mov] => Amministrazione
[total] => 15000
)
)
and
Array (
[0] => Array (
[center] => 8
[caus] => 34
[total] => 38175.04
)
[1] => Array (
[center] => 8
[caus] => 35
[total] => 6132.00
)
[2] => Array (
[center] => 8
[caus] => 36
[total] => 223.80
)
[3] => Array (
[center] => 8
[caus] => 37
[total] => 114.70
)
[4] => Array (
[center] => 8
[caus] => 38
[total] => 14625.07
)
[5] => Array (
[center] => 8
[caus] => 39
[total] => 7450.48
)
I use this function
function searchForId($id, $array) {
foreach ($array as $key => $val) {
if ($val['caus'] === $id) {
return $key;
}
}
return null;
}
to look in array B for each item of array A with this code:
for($i=0;$i<$length;$i++){
if(searchForId($voce_bdg[$i]['idmov'], $voce_actual)){
$key=searchForId($voce_bdg[$i]['idmov'], $voce_actual);
$actual=$voce_actual[$key]['importo'];
echo '<td class="report">'.number_format($actual,2,',','.').'</td>';
}else{
echo '<td class="report">0,00</td>';
}
}
It works for every item like a charm except for the first item where it returns 0.
Where am I wrong??
Thanks in advance for your help!
Lelio
PHP treats the index 0 as a false. As such, if you find your result in index zero, it won't pass the if() statement you have.
Since your function returns null if no record found, why not try to check for null?
for($i = 0; $i < $length; $i++)
{
// Use is_null() check below. If it is not null, it is found.
// Also, instead of doing searchForId() twice, just do it once and check for the result.
$key = searchForId($voce_bdg[$i]['idmov'], $voce_actual);
if(! is_null ($key))
{
$actual = $voce_actual[$key]['importo'];
echo '<td class="report">'.number_format($actual,2,',','.').'</td>';
}
else
{
echo '<td class="report">0,00</td>';
}
}
try replacing operator === for ==
It does return something. It return 0 since the key is 0. But your if() interpret it as a "false"
change
if(searchForId($voce_bdg[$i]['idmov'], $voce_actual)){
with
if(searchForId($voce_bdg[$i]['idmov'], $voce_actual) != null){

Search array and delete entries

How do a delete all array entries where status equals 0?
That means: $array[1][3]; and $array[4];
Array
(
[1] => Array
(
[id] => 1
[parent_id] => 0
[status] => 2
[title] => bananer
[breadcrumb] => /bananer
[slug] => /bananer
[2] => Array
(
[id] => 2
[parent_id] => 1
[status] => 2
[title] => sub bananer
[breadcrumb] => /bananer/sub bananer
[slug] => /bananer/sub-bananer
)
[3] => Array
(
[id] => 3
[parent_id] => 1
[status] => 0
[title] => sub bananer 2
[breadcrumb] => /bananer/sub bananer 2
[slug] => /bananer/sub-bananer-2
)
)
[4] => Array
(
[id] => 4
[parent_id] => 0
[status] => 0
[title] => appelsin
[breadcrumb] => /appelsin
[slug] => /appelsin
[5] => Array
(
[id] => 5
[parent_id] => 4
[status] => 2
[title] => sub appelsin
[breadcrumb] => /appelsin/sub appelsin
[slug] => /appelsin/sub-appelsin
)
[6] => Array
(
[id] => 6
[parent_id] => 4
[status] => 2
[title] => sub appelsin 2
[breadcrumb] => /appelsin/sub appelsin 2
[slug] => /appelsin/sub-appelsin-2
)
)
)
Try this:
function deleteIt(&$array)
{
foreach($array as $key => &$value)
{
if (is_numeric($key)) deleteIt($value);
if (isset($value['status']) && !$value['status']) unset($array[$key]);
}
}
This runs through the array recursively while handing references down so that the original array is modified while deleting. Notice the & in the deleteIt function prototype and in the foreach.
Something like this may help
function parse($var)
{
foreach($var as $key => $val)
{
if( is_array($val) )
{
parse($val)
}
else
{
if($key == 'status' && $val ==0 )
{
// do something here
}
}
}
}
You can do something that's highly specialized such as:
function stripBadStatus($array) {
foreach($array as $k=>$arr) {
if($arr['status'] == 0) {
unset($array[$k]);
} else if(is_array($arr)) {
foreach($arr as $deepk=>$deeparr) {
if($deeparr['status'] == 0) {
unset($array[$k][$deepk]);
}
}
}
}
return $array;
}

Re-structure array based on parent/child relationship

I have the following array structure:
Array
(
[0] => Array
(
[id] => 83
[parent_id] => 0
[title] => Questionnaire one
)
[1] => Array
(
[id] => 84
[parent_id] => 0
[title] => Questionnaire two
)
[2] => Array
(
[id] => 85
[parent_id] => 83
[title] => Questionnaire three
)
)
I want to re-structure the array so child items are listed under their parents. For example:
Array
(
[0] => Array
(
[id] => 83
[parent_id] => 0
[title] => Questionnaire one
)
[1] => Array
(
[id] => 85
[parent_id] => 83
[title] => Questionnaire three
)
[2] => Array
(
[id] => 84
[parent_id] => 0
[title] => Questionnaire two
)
)
I've searched previous questions but found none of them actually achieve the above.
Can someone please help me with this?
Thanks
You can try
$array = Array(
"0" => Array("id" => 83,"parent_id" => 0,"title" => "Questionnaire one"),
"1" => Array("id" => 84,"parent_id" => 0,"title" => "Questionnaire two"),
"2" => Array("id" => 85,"parent_id" => 83,"title" => "Questionnaire three"));
$id = array_map(function ($item) {return $item["id"];}, $array);
$parent = array_filter($array, function ($item){return $item['parent_id'] == 0;});
$lists = array();
foreach ($parent as $value)
{
$lists[] = $value ;
$children = array_filter($array, function ($item) use($value) {return $item['parent_id'] == $value['id'];});
foreach($children as $kids)
{
$lists[] = $kids ;
}
}
echo "<pre>";
print_r($lists);
Output
Array
(
[0] => Array
(
[id] => 83
[parent_id] => 0
[title] => Questionnaire one
)
[1] => Array
(
[id] => 85
[parent_id] => 83
[title] => Questionnaire three
)
[2] => Array
(
[id] => 84
[parent_id] => 0
[title] => Questionnaire two
)
)
You could use uksort(). Heres a DEMO.
function cmp($a, $b) {
if ($stock[$a] != $stock[$b]) return $stock[$b] - $stock[$a];
return strcmp($a, $b);
}
$a = array(5 => 'apple', 1 => 'banana', 6 => 'orange', 2 => 'kiwi');
uksort($a, "cmp");
foreach ($a as $key => $value) {
echo "$key: $value\n";
}

Categories