How do I move array child value to parent key? - php

I need some clarity as to what PHP function can achieve what I'm aiming for.
This is a PHP array I have:
Array
(
[0] => Array
(
[id] => 6
[index] => 1
[active] => 1
[name] => MyName
)
[1] => Array
(
[id] => 1
[index] => 2
[active] => 1
[name] => YourName
)
[2] => Array
(
[id] => 2
[index] => 4
[active] => 1
[name] => TheirName
)
}
I want to take the "index" value and make it a KEY of that array parent, so the array would become this:
Array
(
[1] => Array
(
[id] => 6
[index] => 1
[active] => 1
[name] => MyName
)
[2] => Array
(
[id] => 1
[index] => 2
[active] => 1
[name] => YourName
)
[4] => Array
(
[id] => 2
[index] => 4
[active] => 1
[name] => TheirName
)
}
Can anyone please tell me how would I do this in PHP?
Thank you in advance.

you can use: array_column($array, null, 'index');
is the better solution, but only work for >= 5.5 php version

Not the most elegant solution, but it works (it doesn't actually move the array, it just generates a new one that corresponds to your requirements):
$resultArr = array();
foreach ($mainArr as $value) {
$resultArr[$value['index']] = $value;
}
unset($mainArr); // or $mainArr = $resultArr;
This way you won't overwrite any existing keys in your original array.

$a = array
(
0 => array
(
"id" => 6,
"index" => 1,
"active" => 1,
"name" => "MyName"
),
1 => Array
(
"id" => 1,
"index" => 2,
"active" => 1,
"name" => "YourName"
),
2 => Array
(
"id" => 2,
"index" => 4,
"active" => 1,
"name" => "TheirName"
)
);
$newArray = array();
foreach ($a as $foo) {
$newArray[$foo['index']] = $foo;
}

You have to do it manually with:
$input = array( /* your data */ );
$output = array();
foreach ( $input as $values ) {
$output[ $values['index'] ] = $values;
}

public static function normArray($key, $inputArray)
{
$outputArray = array();
foreach ($inputArray as $item) {
$index = intval($item[$key]);
$outputArray[$index] = $item;
}
return $outputArray;
}

Related

Get value from array using key

I have an array like this:
Array
(
[0] => Array
(
[settingID] => 1
[name] => audioCueDistance
[setValue] => false
)
[1] => Array
(
[settingID] => 2
[name] => audioCueDistanceToGo
[setValue] => true
)
[2] => Array
(
[settingID] => 3
[name] => audioCues
[setValue] => true
)
[3] => Array
(
[settingID] => 4
[name] => audioCueStyle
[setValue] => default
)
[4] => Array
(
[settingID] => 5
[name] => audioCueTime
[setValue] => true
)
[5] => Array
(
[settingID] => 6
[name] => isMetric
[setValue] => true
)
How can I get individual values from key for example, I would like to output the setValue of isMetric.
Thanks
foreach ($foo as $bar) {
if ($bar['name'] == "isMetric") {
// Use setValue here
}
}
From what I understand you want to do something like $myArray['isMetric']['setValue'].
As your array is not in that form you need to map it that way.
$myArray = array(
array(
'settingID'=>6,
'name'=>'isMetric',
'value'=>true
)
);
$myAssocArray = array_reduce($myArray, function($carry, $item){
$carry[$item['name']] = $item;
return $carry;
}, array());
echo $myAssocArray['isMetric']['setValue'];
Run this code here: https://repl.it/CZ3R
foreach($array as $element)
{
if($element['name'] = 'isMetric')
return $element['setValue'];
}
throw new \Exception('isMetric Not Found.');

merging mutidimensional arrays

I have an array that looks like this:
getting array need to convert array as same key value as 0
foreach($array as $key=>$id){
$consumer_data[]=$this->App_model->get_session($id);
}
print_r($consumer_data);
Array
(
[0] => Array
(
[0] => Array
(
[ConsumerID] => 1
[name] => asdfd
)
[1] => Array
(
[ConsumerID] => 5
[name] => test
)
[2] => Array
(
[ConsumerID] => 3
[name] => test1
)
)
[1] => Array
(
[0] => Array
(
[ConsumerID] => 4
[name] => test4
)
)
i want to implement array like this in same key value as 0
Array
(
[0] => Array
(
[0] => Array
(
[ConsumerID] => 1
[name] => asdfd
)
[1] => Array
(
[ConsumerID] => 5
[name] => test
)
[2] => Array
(
[ConsumerID] => 3
[name] => test1
)
[3] => Array
(
[ConsumerID] => 4
[name] => test4
)
)
I am using PHP. Can anyone point me to a good starting point as to how I should go about doing this?
You can use array_merge():
$new_array[0] = array_merge($array[0], $array[1]);
Where $array is the first array.
SEE DEMO
OR for a more dynamic approach:
$new_array = array(0 => array());
foreach($array as $a) {
$new_array[0] = array_merge($new_array[0], $a);
}
SEE DEMO 2
The simpliest solution is to do it with:
$input = array(
array(
array('ConsumerID' => 1, 'name' => 'asdfd'),
array('ConsumerID' => 5, 'name' => 'test'),
array('ConsumerID' => 4, 'name' => 'test1'),
),
array(
array('ConsumerID' => 4, 'name' => 'test4'),
),
);
$output = array(
array()
);
foreach ($input as $data) {
$output[0] = array_merge($output[0], $data);
}
Try this->
$newArray = array();
foreach($values as $key=>$val){
$newArray [0][$key]=$val;
}
print_r($newArray);
Check this:
<?php
$arr[0] = array(0 => array("ConsumerID" => 1, "name" => "Ni"), 1 => array("ConsumerID" => 2, "name" => "Ab"));
$arr[1] = array(1 => array("ConsumerID" =>5, "name" => "GE"), 1 => array("ConsumerID" => 6, "name" => "DB"));
$new = array();
foreach($arr as $key => $value) {
foreach($value as $innerkey => $innervalue) {
$new[0][] = $innervalue;
}
}
print_r($new);
?>

Count occurrences of a value inside a multidimensional array

so i retrieve a json, convert it into an array and i got this output:
Array
(
[Sid] => 23888555
[pages] => Array
(
[0] => Array
(
[id] => 13111071
[name] => Page 1
[slots] => Array
(
[0] => Array
(
[SlotId] => 6
[info] => Array
(
[id] => 5247
[color] => red
)
)
[1] => Array
(
[SlotId] => 4
[info] => Array
(
[id] => 5267
[color] => blue
)
)
[2] => Array
(
[SlotId] => 7
[info] => Array
(
[id] => 5267
[color] => green
)
)
)
)
[1] => Array
(
[id] => 13111072
[name] => Page 2
[slots] => Array
(
[0] => Array
(
[SlotId] => 6
[info] => Array
(
[id] => 5247
[color] => red
)
)
[1] => Array
(
[SlotId] => 4
[info] => Array
(
[id] => 5267
[color] => blue
)
)
)
)
)
)
I have no problem reading it whatsoever, what i wanna do is count for every page how many similar "last" id i got.
Exemple :
[pages][0][slots][0][info][id]
[pages][0][slots][1][info][id]
[pages][0][slots][3][info][id]
For the page 1, I wanna compare these 3 ids between them and count the occurrences.
[pages][1][slots][0][info][id]
[pages][1][slots][1][info][id]
For the page 2, I wanna compare these 2 ids between them and count the occurrences.
The output i want looks like this :
page 1 -> 1x5247
-> 2x5267
page 2 -> 1x5247
-> 1x5267
EDIT :
I tried using
foreach ($data['pages'] as $item) {
foreach ($item['slots'] as $slotnumber => $value) {
print_r(array_count_values($item['slots'][$slotnumber]['info']));
}
}
which returns me this :
Array ( [5247] => 1 [red] => 1 )
Array ( [5267] => 1 [blue] => 1 )
Array ( [5267] => 1 [green] => 1 )
So i think i might be able to use this but i don't know how.
I manually declared the array and then created the countstuff() function. This should work for you. I tested it and it work on my end. After going through all this trouble, I really do appreciated it if you choose my answer and up vote it.
<?php
$data = Array("Sid" => "23888555", "pages" => Array("0" => Array("id" => "13111071", "name" => "Page 1", "slots" => Array("0" => Array("SlotId" => "6", "info" => Array("id" => "5247", "color" => "red")), "1" => Array("SlotId" => "4", "info" => Array("id" => "5267", "color" => "blue")), "2" => Array("SlotId" => "7","info" => Array("id" => "5267", "color" => "green")))),
"1" => Array
(
"id" => "13111072",
"name" => "Page 2",
"slots" => Array
(
"0" => Array
(
"SlotId" => "6",
"info" => Array
(
"id" => "5247",
"color" => "red"
)
),
"1" => Array
(
"SlotId" => "4",
"info" => Array
(
"id" => "5267",
"color" => "blue"
)
)
)
)
)
);
//End of array declaration
//Now the really convoluted coding starts
//Create a function
function countstuff($yourarray){
foreach($yourarray as $mainarraykey => $mainarray){
if($mainarraykey == "pages"){
foreach($mainarray as $pageskey => $pagesarray){
//echo "Page \"$pageskey\"<br/>";
foreach($pagesarray as $pagessubarraykey => $pagessubarray_array){
if($pagessubarraykey == "slots"){
foreach($pagessubarray_array as $slotskey => $slots){
foreach($slots as $slotssubkey => $slotssub){
if($slotssubkey == "info"){
foreach($slotssub as $key => $value){
if($key == "id"){
//echo $value."<br/>";
$pages[$pageskey][] = $value;
}
}
}
}
}
}
}
}
}
}
return $pages;
}
//Execute the countstuff() function
$output = countstuff($data);
function showresults($input){
foreach($input as $pagekey => $page){
echo "Page $pagekey:<br/>";
$results = array_count_values($page);
foreach($results as $resultkey => $result){
echo $result."x".$resultkey."<br/>";
}
echo "<br/>";
}
}
showresults($output);
?>
I tried some things let me know what you guys think of this.
I get every id then enter them into an array then use array_count_values
$array_ids = array();
foreach ($data['pages'] as $item) {
$numberOfElements = count($item['slots']);
$z= 0;
foreach ($item['slots'] as $slotnumber => $value) {
$array_ids[$z] = $item['slots'][$slotnumber]['info']['id'];
// search for occurrences when the array is full
if (count($array_ids) == $numberOfElements) {
var_dump(array_count_values($array_ids));
// reset the array to 0 every time we loop through the whole infos
$array_ids = array();
}
$z++;
}
}
This seems to work for every page.
array (size=2)
5267 => int 2
5247 => int 1
array (size=2)
5267 => int 1
5247 => int 1

Group rows of a multidimensional array and form comma-separated values within each group

I want to combine arrays having same category id and question id.
Sample input:
$array = [
[
'category_id' => 1,
'question_id' => 1,
'option_id' => 2,
'title' => 'Do you wear glasses?',
'answer' => 'no'
],
[
'category_id' => 1,
'question_id' => 2,
'option_id' => 3,
'title' => 'Your hobbies ?',
'answer' => 'movies'
],
[
'category_id' => 1,
'question_id' => 4,
'option_id' => 8,
'title' => 'what is your status?',
'answer' => 'single'
],
[
'category_id' => 1,
'question_id' => 2,
'option_id' => 1,
'title' => 'Your hobbies ?',
'answer' => 'travel'
],
];
The 2nd and 4th arrays contain the same question (same category id and same question id), so I would like to have their answer values merged together as a comma-separated string.
Desired result:
Array(
[0] => Array
(
[category_id] => 1
[question_id] => 1
[option_id] => 2
[title] => Do you wear glasses?
[answer] => no
)
[1] => Array
(
[category_id] => 1
[question_id] => 2
[option_id] => 3
[title] => Your hobbies ?
[answer] => movies,travel
)
[2] => Array
(
[category_id] => 1
[question_id] => 4
[option_id] => 8
[title] => what is your status?
[answer] => single
)
)
It is okay that the option id and title are overwritten while grouping because I am not using the option id and the title values will be identical within each group.
maybe something like this could work, not sure if there's a better way to do it tho:
new_array=array();
foreach($source_array as $e){
$insert=1;
foreach($new_array as $n)
if(array_search($e['title'], $n)==false){
$n['answer'].=", ".$e['answer'];
$insert=0;
}
}
if($insert){
$new_array[]=$e;
}
}
For an example array
Array
(
[0] => Array
(
[category_id] => 1
[question_id] => 1
)
[1] => Array
(
[category_id] => 2
[question_id] => 2
)
[2] => Array
(
[category_id] => 1
[question_id] => 1
)
)
You could do something like this as an illustration
// Define the array to work on
$array = array( array( 'category_id' => 1, 'question_id'=> 1), array( 'category_id' => 2, 'question_id' => 2), array( 'category_id' => 1, 'question_id' => 1));
// Initialize the result array containing only unique question_id/category_id combinations
$unique_array = array();
foreach ($array as $key) {
if (!count($unique_array)) {
$unique_array[] = $key;
} else {
$unique = 1;
foreach ($unique_array as $check) {
if ( $check['category_id'] == $key['category_id'] && $check['question_id'] == $key['question_id'] ) {
$unique = 0;
}
}
if ( $unique ) {
$unique_array[] = $key;
}
}
}
print_r($unique_array);
The output of the last print_r would be
Array
(
[0] => Array
(
[category_id] => 1
[question_id] => 1
)
[1] => Array
(
[category_id] => 2
[question_id] => 2
)
)
The reason I ask if order matters, is that if it doesn't matter, you can sort your array first, and then only compare each one to its previous sibling:
$source=array(array("cat_id"=>1,"ques_id"=>1,"opt_id"=>2,"title"=>"cid:1, qid:1, oid:2","answer"=>"whatever"),array("cat_id"=>1,"ques_id"=>2,"opt_id"=>3,"title"=>"cid:1, qid:2, oid:3","answer"=>"whatever"),array("cat_id"=>1,"ques_id"=>4,"opt_id"=>8,"title"=>"cid:1, qid:4, oid:8","answer"=>"whatever"),array("cat_id"=>1,"ques_id"=>2,"opt_id"=>1,"title"=>"cid:1, qid:2, oid:1","answer"=>"whtvr"));
print_r($source); // just to debug
usort($source,function($a,$b){
if($a["cat_id"]<$b["cat_id"])
return -1;
elseif($a["cat_id"]>$b["cat_id"])
return 1;
elseif($a["ques_id"]<$b["ques_id"])
return -1;
elseif($a["ques_id"]>$b["ques_id"])
return 1;
elseif($a["opt_id"]<$b["opt_id"])
return -1;
elseif($a["opt_id"]>$b["opt_id"])
return 1;
else
return 0;
});
$source=array_reduce($source,function(&$a,$b){
if(empty($a))
{
$a=array($b);
}
else
{
$cache=array_pop($a);
if($cache["cat_id"]==$b["cat_id"] && $cache["ques_id"]==$b["ques_id"])
{
$cache["answer"].=", ".$b["answer"];
$a[]=$cache;
}
else
{
$a[]=$cache;
$a[]=$b;
}
}
return $a;
},array());
print_r($source);
Outputs:
// first print_r
Array
(
[0] => Array
(
[cat_id] => 1
[ques_id] => 1
[opt_id] => 2
[title] => cid:1, qid:1, oid:2
[answer] => whatever
)
[1] => Array
(
[cat_id] => 1
[ques_id] => 2
[opt_id] => 3
[title] => cid:1, qid:2, oid:3
[answer] => whatever
)
[2] => Array
(
[cat_id] => 1
[ques_id] => 4
[opt_id] => 8
[title] => cid:1, qid:4, oid:8
[answer] => whatever
)
[3] => Array
(
[cat_id] => 1
[ques_id] => 2
[opt_id] => 1
[title] => cid:1, qid:2, oid:1
[answer] => whtvr
)
)
// second print_r
Array
(
[0] => Array
(
[cat_id] => 1
[ques_id] => 1
[opt_id] => 2
[title] => cid:1, qid:1, oid:2
[answer] => whatever
)
[1] => Array
(
[cat_id] => 1
[ques_id] => 2
[opt_id] => 1
[title] => cid:1, qid:2, oid:1
[answer] => whtvr, whatever
)
[2] => Array
(
[cat_id] => 1
[ques_id] => 4
[opt_id] => 8
[title] => cid:1, qid:4, oid:8
[answer] => whatever
)
)
Please be noted that you stated in your comment that option_id is irrelevant, so I didn't replace it; you can replace that too inside the anonymous function inside array_reduce if you need to.
$data = array();
//$new is the array in which you have data originally
foreach($new as $arrayK => $arrayV){
if(!isset($data[$arrayV['category_id']][$arrayV['question_id']]))
$data[$arrayV['category_id']][$arrayV['question_id']] = $arrayV;
else{
$option = $data[$arrayV['category_id']][$arrayV['question_id']]['option_id'] . ',' . $arrayV['option_id'];
$data[$arrayV['category_id']][$arrayV['question_id']]['option_id'] = $option;
$answer = $data[$arrayV['category_id']][$arrayV['question_id']]['answer'] . ',' . $arrayV['answer'];
$data[$arrayV['category_id']][$arrayV['question_id']]['answer'] = $answer;
}
}
$data will have the required data in mentioned format
Both answer and option will be comma seperated
foreach($arr as $k=>$a)
{
$common[$k] = search($arr,'category_id',$a['category_id'],'question_id',$a['question_id']);
$answers = array_map(function($item) { return $item['answer']; }, $common[$k]);
$options = array_map(function($item) { return $item['option_id']; }, $common[$k]);
foreach($common[$k] as $temp)
{
$finalAns = $temp;
$finalAns['answer'] = implode(",",$answers);
$finalAns['option_id'] = implode(",",$options);
}
$final[] = $finalAns;
}
$final = array_map("unserialize", array_unique(array_map("serialize", $final)));
echo "<pre>";
print_r($final);
Put Below function in your common function file or in same file.
function search($array, $key, $value, $key1, $value1)
{
$results = array();
if (is_array($array))
{
if (isset($array[$key]) && $array[$key] == $value && isset($array[$key1]) && $array[$key1] == $value1)
{
$results[] = $array;
}
foreach ($array as $subarray)
$results = array_merge($results, search($subarray, $key, $value,$key1,$value1));
}
return $results;
}
Your output would be
Array
(
[0] => Array
(
[category_id] => 1
[question_id] => 1
[option_id] => 2
[title] => Do you wear glasses?
[answer] => no
)
[1] => Array
(
[category_id] => 1
[question_id] => 2
[option_id] => 3,1
[title] => Your hobbies ?
[answer] => movies,travel
)
[2] => Array
(
[category_id] => 1
[question_id] => 4
[option_id] => 8
[title] => what is your status?
[answer] => single
)
)
There is no reason for convoluted logic or multiple loops.
Each group needs to have a unique identifier. Although the asker states that question_id is enough, you can guarantee uniqueness by combining question_id and category_id as a delimited string. Use this "composite identifier" as the first-level key while pushing data into the result array.
When a composite key is re-encountered ), then do not both to save all data -- only append data to the desired element(s).
When finished iterating, re-index the result array to remove the temporary composite keys (if you wish).
Code: (Demo)
$result = [];
foreach ($array as $row) {
$compositeKey = $row['category_id'] . '_' . $row['question_id'];
if (!isset($result[$compositeKey])) {
$result[$compositeKey] = $row;
} else {
$result[$compositeKey]['answer'] .= ",{$row['answer']}";
}
}
var_export(
array_values(
$result
)
);
P.s. Typically, it is better to form subarrays instead of comma-delimited strings. Subarrays allows better access to individual values and flexibility in presentation. If you ever change your mind about how to present the values, you'd otherwise need to remove or replace the commas and print something else. Save the hassle, leave presentation to your (view) presentation loop and implode the subarray values exactly as you wish.

Remove duplicate elements off a multi-dimension array

I have an array contain this data
Array
(
[id] => Array
(
[0] => 1
[1] => 10
[2] => 4
)
[age] => Array
(
[0] => 1
[1] => 1
[2] => 2
)
)
Now I want to remove duplicates from the ['age'] and leave the first one in tact.
So this would return
Array
(
[id] => Array
(
[0] => 1
[2] => 4
)
[age] => Array
(
[0] => 1
[2] => 2
)
)
Any ideas? Or is there a function already in place to do this?
Like Gordon said, you'd need a custom function to make the relationship but you can use http://php.net/manual/en/function.array-unique.php ?
Wouldn't it be better to have the keys of the age array the corresponding values of the id array?
<?php
$array = array(
'id' => array(0 => 1, 1 => 10, 3 => 4),
'age' => array(0 => 1, 1 => 1, 2 => 2)
);
array_walk($array, 'dupe_killer');
print_r($array);
function dupe_killer(&$value, $key)
{
$value = array_unique($value);
}
?>
You could try this
$array = array('id' => array(1,10,4), 'age'=>array(1,1,2));
$age_array = array();
foreach ($array['age'] as $key => $val) {
if (in_array($val, $age_array))
unset($array['id'][$key], $array['age'][$key]);
$age_array[] = $val;
}
print_r($array);
this returns Array ( [id] => Array ( [0] => 1 [2] => 4 ) [age] => Array ( [0] => 1 [2] => 2 ) )
Regards
Luke

Categories