Processing data from query - php

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].

Related

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;
}, []);

array_push to a multidimensional array if array_key_exists

I am creating a new array ($Parts) from an existing array ($newarray), and reordering the array. However if the array key exists in the new array, I want to append to the 'location' and 'qty' arrays.
Here is what the new array structure looks like:
'4117-0171-249' =>
'pri_id' => '859'
'vendor' => 'R01298'
'score' => '0.00'
'location' =>
0 => '10103'
'qty' =>
0 => '70'
Here is my code I am using.
$Parts = array();
foreach($newarray AS $Ke => $Va) {
if(array_key_exists($Va['part_number'], $Parts)){
array_push($Parts[$location][],$Va['location']);
} else {
$Parts[$Va['part_number']] = array('pri_id' => $Va['pri_id'],
'vendor' => $Va['vendor'],
'score' => $Va['Score'],
'location' => array($Va['location']),
'qty' => array($Va['qty']),
);
}
}
If anyone stumbles across this in the future, the answer was this:
$Parts[$Va['part_number']]['location'][] = $Va['location'];

Merging two arrays into one array, when found duplicates, replace the old one with a new one

Hi I am new in PHP and I am trying to merge 2 arrays but I don't want to get duplicates.I have been stuck a week now.
I have first array:
$existed_product = array(array('name'=>"pano", 'code'=>"BR0001", 'qty'=>"2", 'price'=>"12"),
array('name'=>"ying", 'code'=>"AB001", 'qty'=>"5", 'price'=>"8"));
And I want to merge the second array:
$new_product= array('name'=>"pano", 'code'=>"BR0001", 'qty'=>"10", 'price'=>"12");
I want to merge them and when it found duplicate product, just replace it with a newer array(has qty=10). The result looks like this:
$final_array=array(array('name'=>"pano", 'code'=>"BR0001", 'qty'=>"10", 'price'=>"12"),
array('name'=>"ying", 'code'=>"AB001", 'qty'=>"5", 'price'=>"8"));
Please help me.Thank you
Assuming new product always is a single array, and code is the identifyer, something like this
$existed_product = array(
array(
'name' => 'pano',
'code' => 'BR0001',
'qty' => '2',
'price' => '12' ),
array(
'name' => 'ying',
'code' => 'AB001',
'qty' => '5',
'price' => '8'
)
);
echo '<pre>', print_r( $existed_product, true ), '</pre>';
$new_product = array(
'name' => 'pano',
'code' => 'BR0001',
'qty' => '10',
'price' => '12'
);
foreach ( $existed_product as $no => $product ) {
if ( $new_product['code'] == $product['code'] ) {
$existed_product[$no]['qty'] = $new_product['qty'];
$existed_product[$no]['price'] = $new_product['price'];
}
}
echo '<pre>', print_r( $existed_product, true ), '</pre>';

Search multidimensional array 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

php create a new array from search results of another array

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);

Categories