I have this array:
$all = array(
'meat' => Object(
'name' => 'meat',
'color' => 'red',
'class' => 'food'
),
'chicken' => Object(
'name' => 'chicken',
'color' => 'white',
'class' => 'food'
),
'apple' => Object(
'name' => 'apple',
'color' => 'green',
'class' => 'Fruit'
),
'blueberry' => Object(
'name' => 'blueberry',
'color' => 'blue',
'class' => 'Fruit'
)
);
and i want to Sort it and rebuild it to be like this:
$theright = array(
array(
'class' => 'food',
'menu' => array(
array(
'name' => 'meat',
'color' => 'red',
),
array(
'name' => 'chicken',
'color' => 'white',
)
)
),
array(
'class' => 'Fruit',
'menu' => array(
array(
'name' => 'apple',
'color' => 'green',
),
array(
'name' => 'blueberry',
'color' => 'blue',
)
)
)
);
I tried to Collect all classes in$all array then compare each value with $all array:
$classArray = array();
foreach($all as $key => $value) {
$classArray[$value->class] = array();
}
foreach($classArray as $key => $value) {
$theright[] = array('class' => $key, 'menu' => array());
}
this code get me this array:
$theright = array(
array(
'class' => 'food',
'menu' => array()
),
array(
'class' => 'Fruit',
'menu' => array()
)
);
and i stop here , how to complete it ?
You could just use the class as a key to group them together. Example:
$food = array();
// gather class
foreach($all as $item) {
if(!isset($food[$item->class])) {
$food[$item->class] = array(
'class' => $item->class,
'menu' => array(
array(
'name' => $item->name,
'color' => $item->name,
)
)
);
} else {
$food[$item->class]['menu'][] = array('name' => $item->name,'color' => $item->color,);
}
}
// simple reindex
$food = array_values($food);
There is no need for a second loop. This should do what you want.
$classMap = array();
foreach ($all as $item)
{
// check if class has been created in the class map
if ( ! array_key_exists($classMap, $item['class']))
{
$classMap[$item['class']] = array(
'class' => $item['class'],
'menu' => array()
);
}
$classMap[$item['class']]['menu'][] = array(
'name' => $item['name'],
'color' => $item['color']
);
}
Try with less loop counts (2)
$all = [];
function getSelectClassData(array &$all)
{
$finalArr = [];
while (count($all) > 1) {
$res = [];
$class = array_values($all)[0]->class;
$selectedDataArr = getSelectSimilerMenuData($all, $class);
$res['class'] = $class;
$res['menu'] = array_values($selectedDataArr);
$all = array_diff_key($all,array_flip(array_keys($selectedDataArr)));
$finalArr[] = $res;
}
return $finalArr;
}
function getSelectSimilerMenuData(array $all, $class)
{
return array_filter(
$all,
function ($e) use ($class) {
return $e->class == $class;
}
);
}
print_r(getSelectClassData($all));
Related
i have a function with a dynamic array.
function doIt($accountid,$targeting){
$post_url= "https://url".$accountid."/";
$fields = array(
'name' => "test",
'status'=> "PAUSED",
'targeting' => array(
$targeting
),
);
$curlreturn=curl($post_url,$fields);
};
And i want to build the array "$fields" dynamically within a foreach loop. Like that:
$accountid="57865";
$targeting=array(
"'device_platforms' => array('desktop'),'interests' => array(array('id' => '435345','name' => 'test')),",
"'device_platforms' => array('mobile'), 'interests' => array(array('id' => '345345','name' => 'test2')),",
);
foreach ($targeting as $i => $value) {
doit($accountid,$value);
}
The Problem is, that the array within the function will not be correctly filled. If i output the array in the function i get something like:
....[0] => array('device_platforms' => array('desktop'),'custom_audiences'=> ['id' => '356346']), )
The beginning [0] should be the problem. Any ideas what im doing wrong?
Hope this will help you out. The problem was the way you are defining $targeting array. You can't have multiple keys with same name
Change 1:
$targeting = array(
array(
'device_platforms' => array('desktop'),
'interests' => array(
array('id' => '435345',
'name' => 'test')),
),
array(
'device_platforms' => array('mobile'),
'interests' => array(
array('id' => '345345',
'name' => 'test2'))
)
);
Change 2:
$fields = array(
'name' => "test",
'status' => "PAUSED",
'targeting' => $targeting //removed array
);
Try this code snippet here this will just print postfields
<?php
ini_set('display_errors', 1);
function doIt($accountid, $targeting)
{
$post_url = "https://url" . $accountid . "/";
$fields = array(
'name' => "test",
'status' => "PAUSED",
'targeting' => $targeting
);
print_r($fields);
}
$accountid = "57865";
$targeting = array(
array(
'device_platforms' => array('desktop'),
'interests' => array(
array('id' => '435345',
'name' => 'test')),
),
array(
'device_platforms' => array('mobile'),
'interests' => array(
array('id' => '345345',
'name' => 'test2'))
)
);
foreach ($targeting as $i => $value)
{
doit($accountid, $value);
}
I have the following array. I'm not even sure if that array is properly formatted. I am not even sure if my array is right.
I want to convert the following array to a serialized XML using PHP. I am using attr tag for the attributes.
Here is the array:
$data = Array(
'name' => 'account',
'attr' => Array(
'id' => 123456
),
'children' => Array(
Array(
'name' => 'name',
'attr' => Array(),
'children' => Array(
'BBC'
),
),
Array(
'name' => 'monitors',
'attr' => Array(),
'children' => Array(
Array(
'name' => 'monitor',
'attr' => Array(
'id' => 5235632
),
'children' => Array(
Array(
'name' => 'url',
'attr' => Array(),
'children' => Array(
'http://www.bbc.co.uk/'
)
)
)
),
Array(
'name' => 'monitor',
'attr' => Array(
'id' => 5235633
),
'children' => Array(
Array(
'name' => 'url',
'attr' => Array(),
'children' => Array(
'http://www.bbc.co.uk/news'
)
)
)
)
)
)
)
);
It is quite easy with a recursive function. Your basic array contains 3 elements, the name, the attribute list and the children. So your function has to create and append a node with the name, set all attributes and iterate the child data. If the child is an scalar it is a text node, for an array call the function itself.
function appendTo($parent, $data) {
$document = $parent->ownerDocument ?: $parent;
$node = $parent->appendChild($document->createElement($data['name']));
if (isset($data['attr']) && is_array($data['attr'])) {
foreach ($data['attr'] as $name => $value) {
$node->setAttribute($name, $value);
}
}
if (isset($data['children']) && is_array($data['children'])) {
foreach ($data['children'] as $name => $childData) {
if (is_scalar($childData)) {
$node->appendChild($document->createTextNode($childData));
} elseif (is_array($childData)) {
appendTo($node, $childData);
}
}
}
}
$document = new DOMDocument();
$document->formatOutput = TRUE;
appendTo($document, $data);
echo $document->saveXml();
Output:
<?xml version="1.0"?>
<account id="123456">
<name>BBC</name>
<monitors>
<monitor id="5235632">
<url>http://www.bbc.co.uk/</url>
</monitor>
<monitor id="5235633">
<url>http://www.bbc.co.uk/news</url>
</monitor>
</monitors>
</account>
Try the following function
function assocArrayToXML($root_element_name,$ar)
{
$xml = new SimpleXMLElement("<?xml version=\"1.0\"?><{$root_element_name}></{$root_element_name}>");
$f = function($f,$c,$a) {
foreach($a as $k=>$v) {
if(is_array($v)) {
$ch=$c->addChild($k);
$f($f,$ch,$v);
} else {
$c->addChild($k,$v);
}
}
};
$f($f,$xml,$ar);
return $xml->asXML();
}
echo assocArrayToXML("root",$data);
test it here
Hope this will help.
<?php
function array2xml($arr)
{
$dom = new DomDocument('1.0');
/*
*Create Root
*/
$root = $dom->createElement($arr['name']);
if(isset($arr['attr']) && !empty($arr['attr']))
{
foreach($arr['attr'] as $key=>$val)
$root->setAttribute($key, $val);
}
$root = $dom->appendChild($root);
createChilds($arr['children'], $dom, $root);
header('Content-type: text/xml');
echo $dom->saveXML();
}
function createChilds($arr, $dom, $parent)
{
foreach($arr as $child)
{
if(isset($child['name']))
$node = $dom->createElement($child['name']);
/*
*Add Attributes
*/
if(isset($child['attr']) && !empty($child['attr']))
{
foreach($child['attr'] as $key=>$val)
$node->setAttribute($key, $val);
}
/*
*Add Childs Recursively
*/
if(isset($child['children']) && is_array($child['children']))
{
createChilds($child['children'], $dom, $node);
}
else if(isset($child) && is_string($child))
{
$text = $dom->createTextNode($child);
$parent->appendChild($text);
}
if(isset($node))
$parent->appendChild($node);
}
}
$data = Array(
'name' => 'account',
'attr' => Array(
'id' => 123456
),
'children' => Array(
Array(
'name' => 'name',
'attr' => Array(),
'children' => Array(
'BBC'
),
),
Array(
'name' => 'monitors',
'attr' => Array(),
'children' => Array(
Array(
'name' => 'monitor',
'attr' => Array(
'id' => 5235632
),
'children' => Array(
Array(
'name' => 'url',
'attr' => Array(),
'children' => Array(
'http://www.bbc.co.uk/'
)
)
)
),
Array(
'name' => 'monitor',
'attr' => Array(
'id' => 5235633
),
'children' => Array(
Array(
'name' => 'url',
'attr' => Array(),
'children' => Array(
'http://www.bbc.co.uk/news'
)
)
)
)
)
)
)
);
array2xml($data);
?>
Let's say i have an array like this:
$array = array(
0 =>
array (
'value' => '1' ,
'name' => 'dasdfa sadfa' ),
1=> Array (
'value' => 'adresa#gmail.com' ,
'name' => 'd2' ),
21 =>
array(
'value' => 'adresa#gmail.com' ,
'name' => 'name1`' ),
23 =>
array(
'value' => 'popescu.catalina#gmail.com' ,
'name' => 'POPESCU CATALINA' ),
24 =>
array(
'value' => 'popescu.catalina#gmail.com' ,
'name' => 'POPESCU CATALINA' ),
26 =>
array(
'value' => 'ricardo.ramos#amadeus.com',
'name' => '43414 Test01'),
27 =>
array(
'value' => 'sta3no213123ct3av#yahoo.com',
'name' => 'oct oct' )
);
I want to know if exists duplicated value in array with key 'value' I know how to do this if i want a specified value but general no. The result must be an array with no duplicated values(eg:
$array = array(
0 =>
array (
'value' => '1' ,
'name' => 'dasdfa sadfa' ),
1=> Array (
'value' => 'adresa#gmail.com' ,
'name' => 'd2' ),
23 =>
array(
'value' => 'popescu.catalina#gmail.com' ,
'name' => 'POPESCU CATALINA' ),
26 =>
array(
'value' => 'ricardo.ramos#amadeus.com',
'name' => '43414 Test01'),
27 =>
array(
'value' => 'sta3no213123ct3av#yahoo.com',
'name' => 'oct oct' )
);`
Please help me.
This is my try
function has_dupes($array){
$dupe_array = array();
foreach($array as $val){
if(++$dupe_array[$val] > 1){
return true;
}
}
return false;
}
Try this way:
$array = array(
'0' =>
array (
'value' => '1' ,
'name' => 'dasdfa sadfa' ),
'1'=> Array (
'value' => 'adresa#gmail.com' ,
'name' => 'd2' ),
'21' =>
array(
'value' => 'adresa#gmail.com' ,
'name' => 'name1`' ),
'23' =>
array(
'value' => 'popescu.catalina#gmail.com' ,
'name' => 'POPESCU CATALINA' ),
'24' =>
array(
'value' => 'popescu.catalina#gmail.com' ,
'name' => 'POPESCU CATALINA' ),
'26' =>
array(
'value' => 'ricardo.ramos#amadeus.com',
'name' => '43414 Test01'),
'27' =>
array(
'value' => 'sta3no213123ct3av#yahoo.com',
'name' => 'oct oct' )
);
$array = array_map("unserialize", array_unique(array_map("serialize", $array)));
$result = array_unique($array);
print_r($result);
And if you want to store all unique data in one array do it like this:
//declare $array
$unique_array = array();
foreach ($array as $key => $type) {
foreach($type as $vale => $name) {
if ($vale == 'value') {
//echo $name . '<br>';
array_push($unique_array, $name);
}
}
}
$result = array_unique($unique_array);
foreach ($result as $res) {
echo $res . '<br>';
}
Try this
$values = array_map("unserialize", array_unique(array_map("serialize", $array)));
foreach ($values as $key => $value)
{
if ( is_array($value) )
{
$values[$key] = $value;
}
}
print_r($values);
$unique_data = array(); // the result array
$duplicate_data = array();
$seen = array();
foreach ($array as $key => $arr) {
$value = $arr['value'];
if (!isset($seen[$value])) {
$seen[$value] = '';
$unique_data[$key] = $arr;
} else {
$duplicate_data[$key] = $arr; // optional
}
}
unset($seen); // optional in function scope
I have array:
$adm_menu_old = array (
array(
'id' => 1,
'name' => 'Test1',
),
array(
'id' => 3,
'name' => 'Test3',
'childrens' => array(
array(
'id' => 31,
'name' => 'Test31',
),
array(
'id' => 32,
'name' => 'Test32',
'childrens' => array(
array(
'id' => 321,
'name' => 'Test321',
),
),
)
),
array(
'id' => 4,
'name' => 'Test4',
),
);
Say i know id value.
I need get path with all parents of this id.
For example i need get path to this element: id=321
i need get array with key name values:
array('Test3','Test32','Test321')
how should look like recursive function?
Try this function:
function getNames($id, $arr) {
$result = array();
foreach($arr as $key => $val) {
if(is_array($val)) {
if($val["id"] == $id) {
$result[] = $val["name"];
} elseif(!empty($val["childrens"]) && is_array($val["childrens"])) {
$sub_res = getNames($id, $val["childrens"]);
if(count($sub_res) > 0) {
$result[] = $val["name"];
$result = array_merge($result, $sub_res);
}
}
}
}
return $result;
}
i managed to dynamically create my arrays (as $$myGenre contains each name => id), but $myGenre does not contain anything... how can i make this work : $myGenre should contain every $$myGenre, $$myGenre should have its content as name => id, and we should keep each $myGenre separated from one another (here, because of the foreach, we're overriding $myGenre for each different genre) :
<?php function findSection() {
global $post, $custom_meta_fields, $myGenre;
foreach ($custom_meta_fields as $fields) {
foreach ($fields as $field) {
if ($field == $fields['genre']) {
$myGenre = array($field['title']);
$$myGenre = array();
} else {
${$myGenre}[$field['name']] = $field['id'];
}
}
var_dump($$myGenre);
}
}
$custom_meta_fields = array(
array( //THRILLER
'genre' => array( 'title' => 'Thriller'),
'fields' => array(
'name' => 'Movie1',
'desc' => 'Desc movie1',
'id' => 'id1',
'type' => 'text'),
array(
'name' => 'Movie2',
'desc' => 'desc movie2',
'id' => 'id2',
'type' => 'text'
),
array(
'name' => 'movie3',
'desc' => 'desc',
'id' => 'id3',
'type' => 'image'
)
),
array(
'genre' => array( 'title' => 'Action'),
'fields' => array('name' => 'Action1',
'desc' => 'desc act1',
'id' => 'idAction1')
)
);
findSection();
Thanks for your help
I modified your code so that it uses associative arrays, since you were doing pretty weird things with your double dollars.
<?php
function findSection() {
global $post, $custom_meta_fields, $myGenre;
foreach ($custom_meta_fields as $fields) {
foreach ($fields as $field) {
if ($field == $fields['genre']) {
$genre =$field['title'];
$all[$genre]= array();
} else {
$all[$genre][$field['name']] = $field['id'];
}
}
}
echo "<pre>".var_export($all,TRUE)."</pre>";
}
Result:
array (
'Thriller' =>
array (
'Movie1' => 'id1',
'Movie2' => 'id2',
'movie3' => 'id3',
),
'Action' =>
array (
'Action1' => 'idAction1',
),
)