Search multidimensional array php - php

I have the following multidimensional array.
$arr = array(
0 => array(
'id' => 1,
'title' => 'title1',
'url' => 'http://www.foo.bar/',
'blurb' => 'blurb1',
'custodian' => 'custodia1',
'tags' => 'tag1',
'active' => 'Y',
),
1 => array(
'id' => '2',
'title' => 'title2',
'url' => 'http://www.foo.bar/',
'blurb' => 'blurb2',
'custodian' => 'custodia2',
'tags' => 'tag1,tag2',
'active' => 'Y',
),
2 => array(
'id' => '3',
'title' => 'title3',
'url' => 'http://www.foo.bar/',
'blurb' => 'blurb3',
'custodian' => 'custodia3',
'tags' => 'tag1,tag2,tag3',
'active' => 'Y',
),
);
I need to filter the array so that only the arrays with "tag2" in the tags value are displayed.
I've looked at array_filter but just can't get my head around it.
Here is my attempt but it doesn't work at all. not sure what I'm doing wrong.
$filterArr = array_filter($arr, function($tag) {
return ($tag['tags'] == 'tag2');
});

The simplest way is to use foreach loop and in the body of loop check for 'tag2'
If you need to delete all rows without tag2 in tags you can use next loop:
foreach ($arr as $key => $value) {
if (!preg_match('/\btag2\b/',$value['tags'])) {
unset($arr[$key]);
}
}

you could use array_filter and provide the right callback
$result = array_filter($arr,function($t){
return in_array('tag2',explode(',',$t['tags']));
});

array_filter takes each element of the array and passes it to the specified function, in that function you need to return true or false, true if it should stay in and false if it should be filtered out
Use explode and in_array to check for tag2
$filteredArray = array_filter($arr, "filterTag");
function filterTag($arrayElement) {
return in_array("tag2",explode(",",$arrayElement["tags"]));
}
your attempt does not work because some of your "tags" contain other words than tags2, like tag1,tag2,tag3 doing a simple == comparison does not search a string for another string

$resultArr = array();
foreach($arr as $curr)
{
$tagsData = explode(',',$curr['tags']);
if(in_array('tag1',$tagsData)
$resultArr[] = $curr;
}
$resultArr is the resulting array containing the arrays with tags having tag1

Related

Filter 2D array using another 2D array where differently keyed column values intersect

I have an array like this:
$array1 = [
[
'Firepack_sn' => '20012205',
'Installation_Date' => '',
'Type' => 'EH',
'Capacity_m3h' => '81',
'Pressure_bar' => '3,4',
'Rpm' => '2930',
'Power_kw' => '72',
],
[
'Firepack_sn' => '20023901',
'Installation_Date' => '',
'Type' => 'DH',
'Capacity_m3h' => '195',
'Pressure_bar' => '4,2',
'Rpm' => '2000',
'Power_kw' => '72',
],
];
And an array2 like this:
$array2 = [
[
'user_id' => '40009',
'firepack_id' => '20012205',
'activated' => '1',
],
[
'user_id' => '40009',
'firepack_id' => '21020393',
'activated' => '0',
],
];
Now I want to filter the first array, so I only get the rows with a Firepack_sn value that exists in array2 as firepack_id.
Desired output:
[
{
"Firepack_sn":"20012205",
"Installation_Date":"",
"Type":"EH","Standard":"VAS",
"Capacity_m3h":"81",
"Pressure_bar":"3,4",
"Rpm":"2930",
"Power_kw":"72"
}
]
How can I achieve this?
Here is a way to do it :
First, you need to extract the firepack_id you need to look for, then you need to loop through $arr1 and check if Firepack_sn is the same than than one of the firepack_id you extracted before, if yes, then you add it to an array.
$arr1 = json_decode('[{"Firepack_sn":"20012205","Installation_Date":"","Type":"EH","Standard":"VAS","Capacity_m3h":"81","Pressure_bar":"3,4","Rpm":"2930","Power_kw":"72","Pump_Type":"KSB KFP50-200","Motor_Type":"DOOSAN PU066 VAS/CEA","Controller_Type":"WB882-E10 VAS","Pump_sn":"085259","Motor_sn":"EARPA209635","Controller_sn":"","Servicelevel":"","Cust_id":"0","Cust_branche":"","Cust_name":"","Cust_address1":"","Cust_zipcode":"","Cust_city":"","Cust_country":"","Cust_Phone":"","Cust_coachlevel":"","Site_Name":"E-set","Site_address1":"","Site_address2":"","Site_address3":"","Site_zipcode":"","Site_city":"","Site_country":"","Site_contact":"","Site_phone":"","activated":"1"},{"Firepack_sn":"20023901","Installation_Date":"","Type":"DH","Standard":"VAS","Capacity_m3h":"195","Pressure_bar":"4,2","Rpm":"2000","Power_kw":"72","Pump_Type":"KSB KFP50-200","Motor_Type":"DOOSAN PU066 VAS/CEA","Controller_Type":"WB882-E10 VAS","Pump_sn":"085259","Motor_sn":"EARPA209635","Controller_sn":"","Servicelevel":"","Cust_id":"0","Cust_branche":"","Cust_name":"","Cust_address1":"","Cust_zipcode":"","Cust_city":"","Cust_country":"","Cust_Phone":"","Cust_coachlevel":"","Site_Name":"D-set","Site_address1":"","Site_address2":"","Site_address3":"","Site_zipcode":"","Site_city":"","Site_country":"","Site_contact":"","Site_phone":"","activated":"0"}]');
$arr2 = json_decode('[{"user_id":"40009","firepack_id":"20012205","activated":"1"},{"user_id":"40009","firepack_id":"21020393","activated":"0"}]');
$firepackIds = array();
foreach($arr2 as $item){
$firepackIds[] = $item->firepack_id;
}
$goodRows = array();
foreach($arr1 as $item){
if(in_array($item->Firepack_sn, $firepackIds)){
$goodRows[] = $item;
}
}
echo json_encode($goodRows);
Hope this helps.
You do not need multiple loops or inefficient iterated in_array() calls. PHP already offers a native function to compare rows between multiple 2D arrays -- array_uintersect(). Because the custom callback uses rows from either array while making comparisons, you must build the callback's logic to fallback to potentially use either array's target column value.
Code: (Demo)
var_export(
array_uintersect(
$array1,
$array2,
fn($a, $b) =>
($a['Firepack_sn'] ?? $a['firepack_id'])
<=>
($b['Firepack_sn'] ?? $b['firepack_id'])
)
);
Output:
array (
0 =>
array (
'Firepack_sn' => '20012205',
'Installation_Date' => '',
'Type' => 'EH',
'Capacity_m3h' => '81',
'Pressure_bar' => '3,4',
'Rpm' => '2930',
'Power_kw' => '72',
),
)

Add a new field to array elements in a foreach PHP - Laravel

I have this variable:
$families = array(
array(
'expand' => '',
'family_id' => 'AAER',
'active' => true,
'description' => 'Wall Art',
'group_id' => 5
),
array(
'expand' => '',
'family_id' => 'EERR',
'active' => true,
'description' => 'Personalised Mugs',
'group_id' => 4
),
);
And I want add to my $families items a field called 'href', like this:
$families = array(
array(
'href' => 'http://mipage/wall-art/AAER',
'expand' => '',
'family_id' => 'AAER',
'active' => true,
'description' => 'Wall Art',
'group_id' => 5
),
array(
'href' => 'http://mipage/personalised-mug/EEER',
'expand' => '',
'family_id' => 'EERR',
'active' => true,
'description' => 'Personalised Mugs',
'group_id' => 4
),
);
To do this I iterate $families in a foreach loop:
foreach($cat['families'] as $cat_fam) {
$cat['families'][]['href'] = 'http//mysite/'.str_slug($cat_fam).'/'.$cat_fam['family_id'];
}
But this not works for me.
How can I make this?
You've to repalce empty [] with the specific key. For this update foreach block to get key of the element and use that inside foreach loop.
$cat['families'][$key] which points to individual element of the families array.
Like this,
foreach($cat['families'] as $key=>$cat_fam) {
$cat['families'][$key]['href'] = 'http//mysite/'.str_slug($cat_fam).'/'.$cat_fam['family_id'];
}
Demo: https://eval.in/636898
just iterate over the array, and add a key ahref
$newArray= array();
foreach($families as $innerArray){
$innerArray['ahref']='YOUR LINK HERE';
$newArray[] = $innerArray;
}
$families = $newArray ;//if you want to update families array
Do something like:
$href = array('href'=>'http://mipage/wall-art/AAER');
$combined_array = array_combine($families[0],$href);
Don't tested but you can try or modify as per your use
Please try this:
I think you also forgot to add index description in your str_slug call.
foreach($cat['families'] as &$cat_fam) {
$cat_fam['href'] = 'http://mysite/'.str_slug($cat_fam['description']).'/'.$cat_fam['family_id'];
}
You can use the php function array_walk
Liek this :
array_walk($cat['families'], function(&$family){
$family['href'] = 'http//mysite/'.str_slug($family).'/'.$family['family_id'];
});
note the $family variable is passed by reference.

multidimensional array - adding a key and value where a key and value is matched

I'm trying to add a key and value (associative) from an array to another array, where one specific key and value match. Here are the two arrays:
$array1 = array(
1 => array(
'walgreens' => 'location',
'apples' => 'product1',
'oranges' => 'product2'
),
2 => array(
'walmart' => 'location',
'apples' => 'product1',
'oranges' => 'product2',
'milk' => 'product3'
)
);
$array2 = array(
1 => array(
'walgreens' => 'location',
'apples' => 'product1',
'oranges' => 'product2',
'bananas' => 'product3',
)
);
Here is the attempt I made at modifying $array1 to have key 'bananas' and value 'product3':
$dataCJ = getCJItem($isbn);
foreach ($array1 as $subKey => $subArray) {
foreach($subArray as $dkey => $dval){
foreach($array2 as $cjk => $cjv){
foreach($cjv as $cjkey => $cjval){
if($dval['walgreens'] == $cjval['walgreens']){
$dval['bananas'] = $cjval['bananas'];
}
}
}
}
}
This doesn't work. How can I fix this?
Change => $dval to => &$dval. Currently you are creating and writing to a new variable and the update will not work in-place.
I would look at array_merge() function!
Here is a start with the PHP doc.
For your specific case, you could do the following :
foreach($array1 as $key1 => $values1){
foreach($array2 as $key2 => $values2){
if($values1[0] == $values2[0]){
$array1[$key1] = array_merge($values1, $values2);
}
}
}
Note to simplify the problem you should inverse the first key=> value pair of the array.
Having an array this way would be a lot simper :
array(
'location' => "The location (eg:walgreens)",
//...
);
This way you could change the comparison to the following instead :
$values1['location'] == $values2['location']
Which would be safer in the case the array is not built with the location as the first pair.

Processing data from query

I'm writing a 'get' function in a model class in codeigniter, but I need to process some of the data as it's returned, ideally without a whole bunch of overhead.
function get_answers($p)
{
$result = $this->db->get_where('answer', array('a_upid_fk' => $p))->result();
// foreach ($result->answer as $ans) {
// $result->answers = explode( '|', $ans, -1 );
// }
return $result;
}
The results look like this:
array (
0 =>
stdClass::__set_state(array(
'aid' => '742',
'a_upid_fk' => '231',
'answer' => '4555|||',
'a_qid_fk' => '70',
'created' => '2012-04-20 15:35:38',
'last_modified' => '2012-04-20 15:36:11',
'revision' => '1',
)),
1 =>
stdClass::__set_state(array(
'aid' => '743',
'a_upid_fk' => '231',
'answer' => NULL,
'a_qid_fk' => '71',
'created' => '2012-04-20 15:35:38',
'last_modified' => '2012-04-20 15:35:38',
'revision' => '1',
)) ...
the problem is the answer is stored as a pipe delimited list of answers, but I want the function to return it as an exploded array instead. I'm not sure of the syntax and how to create and replace or append the array to the array of objects I've pasted above.
You can see some code I've been trying commented out.
Ideally instead of 'answer' => '4555|||',
I would like to have
'answer' => array (
0 => '4555',
1=> '',
2=> '')
I have no problem making the array using explode but I'm not sure how to modify the original codeigniter active-record result.
Loop thru your sub-arrays:
$answer_array = explode('|', $answer);
foreach ($aswer_array as $instance)
{
$result[] = $instance;
}
Define __set_state()), call it using - $subarray = $result[0][$object->answer].

Get key of multidimensional array?

For example, I have multidimensional array as below:
$array = array (
0 =>
array (
'id' => '9',
'gallery_id' => '2',
'picture' => '56475832.jpg'
),
1 =>
array (
'id' => '8',
'gallery_id' => '2',
'picture' => '20083622.jpg'
),
2 =>
array (
'id' => '7',
'gallery_id' => '2',
'picture' => '89001465.jpg'
),
3 =>
array (
'id' => '6',
'gallery_id' => '2',
'picture' => '47360232.jpg'
),
4 =>
array (
'id' => '5',
'gallery_id' => '2',
'picture' => '4876713.jpg'
),
5 =>
array (
'id' => '4',
'gallery_id' => '2',
'picture' => '5447392.jpg'
),
6 =>
array (
'id' => '3',
'gallery_id' => '2',
'picture' => '95117187.jpg'
)
);
How can I get key of array(0,1,2,3,4,5,6)?
I have tried a lot of examples, but nothing has worked for me.
This is quite simple, you just need to use array_keys():
$keys = array_keys($array);
See it working
EDIT For your search task, this function should do the job:
function array_search_inner ($array, $attr, $val, $strict = FALSE) {
// Error is input array is not an array
if (!is_array($array)) return FALSE;
// Loop the array
foreach ($array as $key => $inner) {
// Error if inner item is not an array (you may want to remove this line)
if (!is_array($inner)) return FALSE;
// Skip entries where search key is not present
if (!isset($inner[$attr])) continue;
if ($strict) {
// Strict typing
if ($inner[$attr] === $val) return $key;
} else {
// Loose typing
if ($inner[$attr] == $val) return $key;
}
}
// We didn't find it
return NULL;
}
// Example usage
$key = array_search_inner($array, 'id', 9);
The fourth parameter $strict, if TRUE, will use strict type comparisons. So 9 will not work, you would have to pass '9', since the values are stored as strings. Returns the key of the first occurence of a match, NULL if the value is not found, or FALSE on error. make sure to use a strict comparison on the return value, since 0, NULL and FALSE are all possible return values and they will all evaluate to 0 if using loose integer comparisons.
Try this , I think it will help you.
foreach ($array as $key=>$value)
{
echo $key.'<br/>';
echo $value['id'].'<br/>';
echo $value['gallery_id'].'<br/>';
echo $value['picture'].'<br/><br/>';
}
sometimes it is to easy to find ;)
array_keys($array);
array_keys
Probably http://php.net/manual/en/function.array-keys.php ?
Convert your double dimensional array on your own:
$tmp = null
foreach($array as $key => $value) {
$tmp[] = $key;
}
print_r($tmp);
You mean something like this:
function getKeys($array)
{
$resultArr = array();
foreach($array as $subArr) {
$resultArr = array_merge($resultArr, $subArr);
}
return array_keys($resultArr);
}

Categories