Building an array in PHP with Codeigniter - php

I'm trying to build an array in Codeigniter 3, but I cant seem to structure it properly.
I have 2 tables that I basically need to combine; questions and their associated answers.
SO, basically I need a multidimensional array, each inner array is to contain the question data along with its associated answer data.
This is what I'm doing at the moment:
$question_array = array();
foreach($course_object->result() as $question){
$question_array[] = array (
'question_id' => $question->question_id,
'question' => $question->question,
);
$answer_data = $this->get_answer_data($question->question_id);
foreach($answer_data as $answer){
$question_array[]['answer'] = $answer->answer;
$question_array[]['result'] = $answer->result;
}
}
return $question_array;
But that outputs each question as an array on its own, as well as each answer, i need to combine them somehow. This is what I'm getting:
array(2) {
["question_id"]=>
string(3) "548"
["question"]=>
string(29) "Who enforces fire safety law?"
}
array(1) {
["answer"]=>
string(11) "The Manager"
}
array(1) {
["result"]=>
string(1) "0"
}
array(1) {
["answer"]=>
string(18) "The Fire Authority"
}
array(1) {
["result"]=>
string(1) "1"
}
and this is what i need:
array(2) {
["question_id"]=>
string(3) "548"
["question"]=>
string(29) "Who enforces fire safety law?"
["answer"]=>
string(11) "The Manager"
["result"]=>
string(1) "0"
["answer"]=>
string(18) "The Fire Authority"
["result"]=>
string(1) "1"
}
I've tried things like array_push but I cant seem to get it to work?
Any ideas what I can try?

The easiest way to do it is to create a new array with what you need, and append it to the $question_array, like this. You'll need a new subarray for the answers, because you can't have duplicate keys in an array.
foreach($course_object->result() as $question){
$q_array = array (
'question_id' => $question->question_id,
'question' => $question->question,
'answers' => array()
);
$answer_data = $this->get_answer_data($question->question_id);
foreach($answer_data as $answer){
$q_array['answers'][] = array(
'answer' => $answer->answer,
'result' =>$answer->result
);
}
$question_array[] = $q_array;
}

I think this should work.
$question_array = array();
$i = 0;
foreach($course_object->result() as $question){
$question_array[$i] = array (
'question_id' => $question->question_id,
'question' => $question->question,
);
$answer_data = $this->get_answer_data($question->question_id);
foreach($answer_data as $answer){
$question_array[$i]['answer'][] = $answer->answer;
$question_array[$i]['result'][] = $answer->result;
}
$i++;
}
return $question_array;

Related

PHP Array, if duplicate id concat values and delete duplicate

I have an array like this
array(2) {
["sys_ID"]=> string(32) "ab0ce921dba8a810f6db3892399619d9" ["sites"]=> array(5) {
[0]=> array(2) {
["sys_ID"]=> string(32) "448ce5a1dba8a810f6db3892399619ba" ["service"]=> string(4) "IDMB" } [1]=> array(2) {
["sys_ID"]=> string(32) "448ce5a1dba8a810f6db3892399619ba" ["service"]=> string(4) "ODMB" } [2]=> array(2) {
["sys_ID"]=> string(32) "598ce5a1dba8a810f6db3892399619bc" ["service"]=> string(4) "IDMB" } [3]=> array(2) {
["sys_ID"]=> string(32) "876ce5a1dba8a810f6db38923996199f" ["service"]=> string(4) "IDMB" } [4]=> array(2) {
["sys_ID"]=> string(32) "876ce5a1dba8a810f6db38923996199f" ["service"]=> string(4) "ODMB" } } }
If there is a duplicate ['sys_ID'] I want to change the first ['service'] => "IDMB,ODMB" then delete the duplicate value so there is only 1. So the above would become
array(2) {
["sys_ID"]=> string(32) "ab0ce921dba8a810f6db3892399619d9" ["sites"]=> array(5) {
[0]=> array(2) {
["sys_ID"]=> string(32) "448ce5a1dba8a810f6db3892399619ba" ["service"]=> string(4) "IDMB,ODMB" } [1]=> array(2) {
["sys_ID"]=> string(32) "598ce5a1dba8a810f6db3892399619bc" ["service"]=> string(4) "IDMB" } [2]=> array(2) {
["sys_ID"]=> string(32) "876ce5a1dba8a810f6db38923996199f" ["service"]=> string(4) "IDMB,ODMB" } ]} }
The first array was made getting POST values;
<?php
foreach ($_POST['services'] as $item) {
$parts = explode(',', $item);
$siteID = $parts[1];
$services = $parts[0];
$data['sites'][] = [
'sys_ID' => $siteID,
'service' => $services
];
}
?>
Change the way you generate your array to something like this:
<?php
$data = [
'sites' => [],
];
foreach ($_POST['services'] as $item) {
// Gather your data
$parts = explode(',', $item);
$siteID = $parts[1];
$services = $parts[0];
// Set flag to remember whether you need to add it
$add = true;
// Loop through existing data and check if the sys_ID already exists
foreach ($data['sites'] as &$dataDetails) {
// It does ... so just append your service
if ($dataDetails['sys_ID'] === $siteID) {
$add = false;
$dataDetails['service'] .= ',' . $services;
break;
}
}
// Couldn't find the sys_ID => Add new entry
if ($add) {
$data['sites'][] = [
'sys_ID' => $siteID,
'service' => $services
];
}
}
?>
It will be better to fill the array properly from the beginning; however I will still post a solution. We have the array defined like this:
$arr = array(
'sys_ID' => 'ab0ce921dba8a810f6db3892399619d9',
'sites' => array(
0 => array(
'sys_ID' => "448ce5a1dba8a810f6db3892399619ba",
'service'=> "IDMB"
),
1 => array(
'sys_ID' => "448ce5a1dba8a810f6db3892399619ba",
'service'=> "ODMB"
),
2 => array(
'sys_ID'=> "598ce5a1dba8a810f6db3892399619bc",
'service'=> "IDMB"
),
3 => array(
'sys_ID'=> "876ce5a1dba8a810f6db38923996199f",
'service'=> "IDMB"
),
4 => array(
'sys_ID'=> "876ce5a1dba8a810f6db38923996199f",
'service'=> "ODMB"
)
)
);
To merge the elements like described, you can do the following loop:
// For each site (1)...
for($i=0; $i<count($arr["sites"])-1; $i++){
// Take each of sites starting from the next one to the end (2)
for($j=$i+1; $j<count($arr["sites"]); $j++){
// If there is a match in sys_ID beteen (1) and (2)
if($arr["sites"][$i]['sys_ID'] == $arr["sites"][$j]['sys_ID']){
// Merge the service into (1) with comma separation
$arr["sites"][$i]['service'] = $arr["sites"][$i]['service'].",".$arr["sites"][$j]['service'];
// then delete (2)
array_splice($arr["sites"],$j,1);
$j--;
}
}
}
Note that this will reindex the numebers (1,2,3...). If you wish to preserve them, you can use unset() instead.

Traverse an STD Class object inside an array

I've send an Array with data through FormData with Ajax.
I json encoded it first before sending it through and decoded it back at the PHP side.
My problem is this: "Trying to get property 'ID' of non-object" Or "Illegal string offset ID"
which is weird, since my array is like:
array(7) {
[0]=>
object(stdClass)#779 (2) {
["ID"]=>
string(1) "1"
["Value"]=>
string(19) "Onbeperkt helpdesk."
}
[1]=>
object(stdClass)#780 (2) {
["ID"]=>
string(1) "2"
["Value"]=>
string(43) "Een direct aanspreekpunt voor al uw vragen."
}
[2]=>
object(stdClass)#781 (2) {
["ID"]=>
string(1) "3"
["Value"]=>
string(20) "Een stabiel netwerk."
}
[3]=>
object(stdClass)#782 (2) {
["ID"]=>
string(1) "4"
["Value"]=>
string(43) "Uw belangrijke gegevens optimaal beveiligd."
}
}
The way I tried traversing the array:
$voordelen = json_decode($_POST['voordelen']);
echo var_dump($voordelen);
for ($i = 0; $i < count($voordelen); $i++) {
foreach ($voordelen[$i] as $key => $item) {
$voorArray = array(
"id" => $item->ID,
"item" => $item->Value,
"content_id" => $content->id // variable from code not shown here.
);
}
}
I also tried:
for ($i = 0; $i < count($voordelen); $i++) {
foreach ($voordelen[$i] as $item) {
$voorArray = array(
"id" => $item->ID,
"item" => $item->Value,
"content_id" => $content->id // Variable from code not shown here.
);
}
}
I also tried using $var['value'] instead of $var->value
But now I'm at a loss. Any help would be appreciated.
I think you are making an extra loop, did you try:
foreach ($voordelen as $item) {
$voorArray = array(
"id" => $item->ID,
"item" => $item->Value,
"content_id" => $content->id // Variable from code not shown here.
);
var_dump($voorArray);
}
What's wrong with just looping through it, since $voordelen is already an array:
$voordelen = json_decode($_POST['voordelen']);
foreach( $voordelen as $item )
{
$voorArray = array(
"id" => $item->ID,
"item" => $item->Value,
"content_id" => $content->id
);
// Do something with $voorArray here.
}

How can I flatten a Multidimensional array into a string?

Ive researched this but im coming up blank, Im generating an array of tests from a database like so:
$descriptions = array();
foreach ($tests as $value) {
array_push($descriptions, ['name' => $value['name']]);
}
I'm getting the desired out put but i'm getting a Multidimensional array of an array with '[64]' arrays inside '$descriptions', I need to convert this array so I get the following output:
'name' => $value1, 'name' => $value2, etc etc for all results,
I've tried implode, array_merge etc but the closest I've got is a flat array with only my last test: [name] => Zika can anyone point me in the right direction? cheers
You can't have duplicate array keys. But you can pass an array in like so:
<?php
$descriptions = array();
$tests = array(
'Zika', 'SARS', 'AIDS', 'Mad Cow Disease', 'Bird Flu', 'Zombie Infection',
);
foreach ($tests as $value) {
$descriptions[] = array('name' => $value);
}
var_dump($descriptions);
Which gives you :
array(6) { [0]=> array(1) { ["name"]=> string(4) "Zika" } [1]=> array(1) { ["name"]=> string(4) "SARS" } [2]=> array(1) { ["name"]=> string(4) "AIDS" } [3]=> array(1) { ["name"]=> string(15) "Mad Cow Disease" } [4]=> array(1) { ["name"]=> string(8) "Bird Flu" } [5]=> array(1) { ["name"]=> string(16) "Zombie Infection" } }
So you could foreach ($descriptions as $desc) and echo $desc['name']';
Have a look here: https://3v4l.org/pWSC6
If you just want a string, try this:
<?php
$descriptions = '';
$tests = array(
'Zika', 'SARS', 'AIDS', 'Mad Cow Disease', 'Bird Flu', 'Zombie Infection',
);
foreach ($tests as $value) {
$descriptions .= 'name => '.$value.', ';
}
$descriptions = substr($descriptions, 0, -2); // lose the last comma
echo $descriptions;
Which will output:
name => Zika, name => SARS, name => AIDS, name => Mad Cow Disease, name => Bird Flu, name => Zombie Infection
See it here https://3v4l.org/OFGF4

Compare and remove from multidimensional array

I've got a multidimensional array as follows:
array(2) {
[0]=>
array(8) {
["id"]=>
string(3) "117"
["promotiontype_id"]=>
string(1) "1"
["groupa_id"]=>
string(3) "390"
["groupb_id"]=>
string(3) "390"
["varx"]=>
string(1) "2"
["vary"]=>
string(1) "1"
["varz"]=>
string(0) ""
["totaldiscount"]=>
float(6.5)
}
[1]=>
array(8) {
["id"]=>
string(3) "117"
["promotiontype_id"]=>
string(1) "1"
["groupa_id"]=>
string(3) "390"
["groupb_id"]=>
string(3) "390"
["varx"]=>
string(1) "2"
["vary"]=>
string(1) "1"
["varz"]=>
string(0) ""
["totaldiscount"]=>
float(7.0)
}
}
So, as you'll see, the first array has a "totaldiscount" of 6.5, the second has 7.0.
Essentially, I need to remove the array that contains the lowest value, so in this instance, it would be array [0] that gets removed as 6.5 has the lowest "totaldiscount". The array could contain more than 2 sub arrays.
I assume it's something to do with foreaching through, but my brain is going in to meltdown with this one!
Any help would be much appreciated!
I am going to divide your question in 2 parts:
How to find the lowest value of x?
function lowestX($array){
$lowest = 999;
for($array as $var){
if($lowest > $var["totaldiscount"]){
$lowest = $var["totaldiscount"];
}
}
}
How do I remove a value from an array?
Use unsset or function.array-splice
A possible solution is to use usort to sort the arrays by "totaldiscount"
Then get the lowest "totaldiscount" value from the sorted arrays.
Then you can loop the sorted arrays (in case there are multiple "totaldiscount" values which have the same lowest value) and unset the array(s) which contains the $lowestTotaldiscount by using the array key.
For example:
<?php
function cmp($a, $b)
{
return ($a["totaldiscount"] < $b["totaldiscount"]) ? -1 : 1;
}
usort($arrays, "cmp");
$lowestTotaldiscount = $arrays[0]["totaldiscount"];
foreach($arrays as $key => $array) {
if ($array["totaldiscount"] === $lowestTotaldiscount) {
unset($arrays[$key]);
}
}
Demo
here is solution of your problem .Simply use array_multisort & unset as given below .
`
$yourArray = array(
array(
"id"=>"117",
"promotiontype_id"=>"1",
"groupa_id"=>"390",
"groupb_id"=> "390",
"varx"=>"2",
"vary"=>"1",
"varz"=> "",
"totaldiscount"=>8.5,
),
array (
"id"=> "117",
"promotiontype_id"=>"1",
"groupa_id"=>"390",
"groupb_id"=>"390",
"varx"=>"2",
"vary"=>"1",
"varz"=>"",
"totaldiscount"=>7.0,
),
array (
"id"=> "117",
"promotiontype_id"=>"1",
"groupa_id"=>"390",
"groupb_id"=>"390",
"varx"=>"2",
"vary"=>"1",
"varz"=>"",
"totaldiscount"=>9.0, )
);
$discount = array();
foreach ($yourArray as $key => $row)
{
$discount[$key] = $row['totaldiscount'];
}
array_multisort($discount, SORT_ASC, $yourArray);
unset($yourArray[0]);
print"<pre>";
print_r($yourArray);`

How to remove duplicate values from an associative array based on a specific value?

I have an array that looks just like that:
array(3) { ["fk_article_id"]=> string(1) "4" ["first_name"]=> string(6) "Ulrike" ["last_name"]=> string(10) "Grasberger" }
array(3) { ["fk_article_id"]=> string(1) "9" ["first_name"]=> string(5) "Frank" ["last_name"]=> string(9) "Neubacher" }
array(3) { ["fk_article_id"]=> string(3) "896" ["first_name"]=> string(2) "D." ["last_name"]=> string(5) "Bauer" }
array(3) { ["fk_article_id"]=> string(3) "896" ["first_name"]=> string(2) "S." ["last_name"]=> string(6) "Anders" }
array(3) { ["fk_article_id"]=> string(3) "896" ["first_name"]=> string(2) "M." ["last_name"]=> string(6) "Tsokos" }
array(3) { ["fk_article_id"]=> string(3) "897" ["first_name"]=> string(8) "Reinhard" ["last_name"]=> string(8) "Scholzen" }
Now what I want to do is to get rid of the duplicate "fk_article_id" values "896", so that only the first of those is left:
array(3) { ["fk_article_id"]=> string(3) "896" ["first_name"]=> string(2) "D." ["last_name"]=> string(5) "Bauer" }
I now array_unique() but I haven't found a possibility to tell the function to only use the values in the "fk_article_id" ID.
How can I do this?
Edit:
It's the output of a three column db table via:
$authors_result = pg_query($query_authors) or trigger_error("An error occurred.<br/>" . mysql_error() . "<br />SQL-Statements: {$searchSQL}");
while ($row = pg_fetch_assoc($authors_result)) {
var_dump($row);
}
A quick way using array_reduce would look like:
$unique = array_reduce($subject, function($final, $article){
static $seen = array();
if ( ! array_key_exists($article['fk_article_id'], $seen)) {
$seen[$article['fk_article_id']] = NULL;
$final[] = $article;
}
return $final;
});
Try a working example.
Edit: Seems you don't want to work with the aggregated results. Here are two other thoughts:
Filtering in PHP
$seen = array();
while ($row = pg_fetch_assoc($authors_result)) {
// Skip this row if we have already seen its article id
if (array_key_exists($row['fk_article_id'], $seen)) {
continue;
}
// Note that we have seen this article
$seen[$row['fk_article_id']] = NULL;
// Do whatever with your row
var_dump($row);
}
Filtering in the DB
The idea here is to change the query being executed so that the repeated article ids do not appear in the result set. How this is done will depend on the query that you're already using.
foreach($array as $key => $value){
if(!in_array( $array[$key]['fk_article_id'], $usedValues)){
$usedValues = $array[$key]['fk_article_id'];
$cleanArray = $array[$key];
}
}
something along thoose lines should do it, i don't think there is an pre existing array funciton for that
** get Unique Associative Array **
using this method you can get easily unique Associative array /Multidimensional Array.
array:6 [▼
0 => array:1 [▼
2 => "Airtel DTH"
]
1 => array:1 [▼
2 => "Airtel DTH"
]
2 => array:1 [▼
2 => "Airtel DTH"
]
3 => array:1 [▼
3 => "NeuSoft PVT LMT"
]
4 => array:1 [▼
3 => "NeuSoft PVT LMT"
]
5 => array:1 [▼
3 => "NeuSoft PVT LMT"
]
]
function assoc_Array_unique($array)
{
$result = array_map("unserialize", array_unique(array_map("serialize", $array)));
foreach ($result as $key => $value)
{
if ( is_array($value) )
{
$result[$key] = assoc_Array_unique($value);
}
}
return $result;
}
$arr_Company= assoc_Array_unique($arr_Company); // get Unique Array
$arr_Company = array_values($arr_Company); Rearrange Index of Array.
I would use a foreach-loop to iterate over the arrays and save all arrays that dont have a duplicate _id to a new array.
$clean = array();
foreach ($arrays as $array) {
if (!isset($clean[$array['fk_article_id']])
$clean[$array['fk_article_id']] = $array;
}
One way would be to iterate over the array, copying ownly the first instance of each fk_article_id in a new array.
<?php
$your_unique_array = array();
foreach ($your_original_array as $v) {
if (!isset($your_unique_array[$v['fk_article_id']) {
$your_unique_array[$v['fk_article_id'] = $v;
}
}

Categories