php create a new array from search results of another array - php

My initial array is
$employees = array(
array('name' => 'jack',
'area' => 'crafts'),
array('name' => 'janet',
'area' => 'aquatics'),
array('name' => 'brad',
'area' => 'crafts')
);
I am trying to create a new array based on the search results of another array so the new array should look like this if I search for 'crafts':
$employees2 = array(
array('name' => 'jack',
'area' => 'crafts'),
array('name' => 'brad',
'area' => 'crafts')
);
What is the simplest solution I can do get get this new result.

foreach($employees as $key => $value){
if($value['area']=='crafts'){
$employees2[] = $value;
}
}
This quite simply loops through the first array and checks the value of "area" in the internal array. If the value is equal to "crafts" you can then put that into a new array which is called $employees2. You can change crafts to whatever you want and add anything you want between the [ ] in employees2 if you wish to customise the key.

Try this:
$employees = array(
array('name' => 'jack',
'area' => 'crafts'),
array('name' => 'janet',
'area' => 'aquatics'),
array('name' => 'brad',
'area' => 'crafts')
);
$employees2 = array();
foreach ($employees as $key) {
if($key['name'] == "jack")
{
array_push($employees2,array('name'=>$key['name'],'area'=>$key['area']));
}
}
var_dump($employees2);
The array_push do all the trick ;)
Saludos.

You could simplify the syntax (but not the algorythmic complexity) by using a utility-belt library Underscore.php (http://brianhaveri.github.com/Underscore.php/)
There's a number of array-"plucking" methods that saves you the need to write loops, but under the bonnet it does much of the same as decribed in answers above.

I will assume that the possible result set can be large. In which case you would want to process the array with as little extra memory as possible. For this I suggest iterating through the array by reference and unsetting the items that do not match your criteria. Possibly less overhead than creating a new array to store the items that match your filter. Then you can check if the array is empty or not to determine if the filter returns any results. Like so:
<?php
// maybe this will be set through an option from the UI
$area_filter = 'crafts';
// fetched results
$employees = array(
array('name' => 'jack',
'area' => 'crafts'),
array('name' => 'janet',
'area' => 'aquatics'),
array('name' => 'brad',
'area' => 'crafts')
);
// filter out the items that match your filter
foreach($employees as $i => &$employee){
if($employee['area'] != $area_filter){
unset($employees[$i]);
}
}
// do something with the results
if(!empty($employees)){
print_r($employees);
} else {
echo "Sorry, your filter '$area_filter' did not match any results\n";
}
?>

Try this :
$employees = array(
array('name' => 'jack',
'area' => 'crafts'),
array('name' => 'janet',
'area' => 'aquatics'),
array('name' => 'brad',
'area' => 'crafts')
);
$employees = array_filter($employees, function($employee) {
return ($employee['area'] == 'crafts' );
});
echo "<pre>";
print_r($employees);

Related

How to use a while loop result within three dimensional array in php?

I would like to pass a while loop result as a value to three dimensional array,i have tried but i couldn't get it.I am trying to solve this from few days.Any suggestions or answers are appreciated.Thank you
$messages = array(
'sender' => "akhil",
'messages' => array(
//////////////while loop starts
while($i < $data){
array(
'number' =>$data[$i],//////here i want to pass the while loop
variable
'text' => rawurlencode('Hello,.........')
)
$i++;
}
/////////////while loop ends
)
);
///the would like to get the below result
$messages = array(
'sender' => "akhil",
'messages' => array(
array(
'number' => 918xxxxxx,
'text' => rawurlencode('Hello,------')
),
array(
'number' => 9196xxxxxx,
'text' => rawurlencode('Hello,----')
)
), array(
'number' => 919xxxxx,
'text' => rawurlencode('Hello,----')
)
)
);
You just need to create the array outside the while loop and then push values into it inside the loop. Your code is almost there...
$messages = array('sender' => "akhil",
'messages' => array()
);
while ($i < count($data)) {
$messages['messages'][] = array('number' => $data[$i],
'text' => rawurlencode('Hello,.........'));
$i++;
}
Demo on 3v4l.org
What you are looking for is called an Anonymous function.
You can achieve your expected behavior by doing this:
'messages' => (function(){
$res = [];
while($i < $data){
$res[] = [
'number' =>$data[$i],//////here i want to pass the while loop variable
'text' => rawurlencode('Hello,.........')
];
$i++;
}
return $res;
})(),
...
I do not know the exact structure of your data, but I would swap the while for an array_map(). It would look like this:
'messages' => array_map(function($d){
return [
'number' =>$d,
'text' => rawurlencode('Hello,.........')
]
},$data),
...
Hohpe that helps,

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.

sorting a multi dimensional array in php

I have an array of arrays, as such
$statuses = array(
[0] => array('id'=>10, 'status' => 'active'),
[1] => array('id'=>11, 'status' => 'closed'),
[2] => array('id'=>12, 'status' => 'active'),
[3] => array('id'=>13, 'status' => 'stopped'),
)
I want to be able to make a new array of arrays and each of those sub arrays would contain the elements based on if they had the same status.
The trick here is, I do not want to do a case check based on hard coded status names as they can be random. I want to basically do a dynamic comparison, and say "if you are unique, then create a new array and stick yourself in there, if an array already exists with the same status than stick me in there instead". A sample result could look something like this.
Ive really had a challenge with this because the only way I can think to do it is check every single element against every other single element, and if unique than create a new array. This gets out of control fast if the original array is larger than 100. There must be some built in functions that can make this efficient.
<?php
$sortedArray = array(
['active'] => array(
array(
'id' => 10,
'status' => 'active'
),
array(
'id' => 12,
'status' => 'active'
)
),
['closed'] => array(
array(
'id' => 11,
'status' => 'active'
)
),
['stopped'] => array(
array(
'id' => 13,
'status' => 'active'
)
),
)
$SortedArray = array();
$SortedArray['active'] = array();
$SortedArray['closed'] = array();
$SortedArray['stopped'] = array();
foreach($statuses as $Curr) {
if ($Curr['status'] == 'active') { $SortedArray['active'][] = $Curr; }
if ($Curr['status'] == 'closed') { $SortedArray['closed'][] = $Curr; }
if ($Curr['status'] == 'stopped') { $SortedArray['stopped'][] = $Curr; }
}
You can also do it with functional way though it's pretty the same like Marc said.
$sorted = array_reduce($statuses, function($carry, $status) {
$carry[$status['status']][] = $status;
return $carry;
}, []);

using yield to return an array of data

I never used generators in PHP. I understand the way to use it :
Foreach an array to do some tasks for each value like greping a specific line into a big file to remove some caracteres..
What I need :
I need to retrieve all bands from my dabatase. Sure I have the 'limit' argument to don't exceed the PHP's memory (there're 30 000 bands..).
I have to filters values and return a new array to the client into my REST API.
What I want to know :
Is it interesting for me to create a method into a trait called 'generator' to perform the code bellow ?
In all cases, I have to create a new array to return it into my method
$bands = Models\Bands::find($bandsParameters);
$json = [];
foreach ($bands as $band) {
$followers = $band->getFollowers();
$followersArr = [];
foreach ($followers as $follower) {
$followerImage = $follower->getImage();
$followerObj = (object)[
'id' => $follower->id,
'username' => $follower->username,
'image' => $followerImage->url,
'online' => $follower->online,
'createdOn' => $follower->createdOn,
'updatedOn' => $follower->updatedOn,
'lastLogin' => $follower->lastLogin,
];
$followersArr[] = $followerObj;
}
$info = $band->getInfo($bandInfoParameters)->getFirst();
$bandObj = (object)[
'id' => $band->id,
'name' => $band->name,
'style' => $band->styles,
'country' => $band->country,
'summary' => isset($info->summary) ? $info->summary : null,
'followers' => $followersArr,
'createdOn' => $band->createdOn,
'updatedOn' => $band->updatedOn,
'authoredBy' => $band->authoredBy,
'updatedBy' => $band->updatedBy,
];
$json[] = $bandObj;
}
return ['key' => 'bands', 'value' => $json];

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.

Categories