How to merge the array value into single array based on group - php

Hi i m looking for a way to merge multiple array value into single array based on the application group. Is there someone who can help me with this problem?
My Array:
Array{
[0]=>Application{
[id]=>1
[name]=>facebook
[group]=>mobile_app
}
[1]=>Application{
[id]=>2
[name]=>youtube
[group]=>mobile_app
}
[2]=>Application{
[id]=>3
[name]=>whatsapp
[group]=>messenger
}
[3]=>Application{
[id]=>4
[name]=>skype
[group]=>messenger
}
}
Requested output:
Array{
[0]=>application{
[id]=>1
[app_name_1]=>facebook
[app_name_2]=>youtube
[group]=>mobile_app
}
[1]=>application{
[id]=>2
[app_name_1]=>whatsapp
[app_name_2]=>skype
[group]=>messenger
}
}

Assume:
$array is equal to:
Array{
[0]=>Application{
[id]=>1
[name]=>facebook
[group]=>mobile_app
}
[1]=>Application{
[id]=>2
[name]=>youtube
[group]=>mobile_app
}
[2]=>Application{
[id]=>3
[name]=>whatsapp
[group]=>messenger
}
[3]=>Application{
[id]=>4
[name]=>skype
[group]=>messenger
}
}
So, for the first array, each element in the array is an instance of the Application Object which should like this:
class Application {
public $id;
public $name;
public $group;
public function __construct($id, $name, $group) {
$this->id = $id;
$this->name = $name;
$this->group = $group;
}
}
And, a few instances of that object make up the array $array
To format it the way you want, you have to first sort them like this:
foreach($array as $element) {
$newAppName = $element->name;
$newArray[$element->group][] = $element->name;
}
And to store objects of them, you need to design a new class like this:
class ApplicationObjectTwo {
public $id;
public $group;
public function __construct($id, $group) {
$this->id = $id;
$this->group = $group;
}
}
And once you do that, you want to create instances of the object and store them in the array like this:
$counter = 1;
$counterTwo = 1;
$otherArray = [];
foreach($newArray as $group => $data) {
$otherArray[] = new ApplicationObjectTwo($counter, $group);
foreach($data as $app) {
$varName = "app_name_" . $counterTwo;
$index = $counter - 1;
$otherArray[$index]->$varName = $app;
$counterTwo++;
}
$counter++;
$counterTwo = 1;
}
And once you do that, you want to print_r($otherArray)
Pastebin for the entire code: http://pastebin.com/S07BMBuV

As I was unsure exactly what you asked for because of youtube being under mobile andmessenger, I just assumed that was a typo. <br>
I have made this example for youbr>
We start off by creating your array and the array you are going to filter into.
$array = array(
array(
"id" => 1,
"name" => "facebook",
"group" => "mobile"
),
array(
"id" => 2,
"name" => "youtube",
"group" => "mobile"
),
array(
"id" => 3,
"name" => "whatsapp",
"group" => "messenger"
),
array(
"id" => 4,
"name" => "skype",
"group" => "messenger"
)
);
$req_array = array(
"mobile" => array(
),
"messenger" => array(
)
);
Then we loop through all our sub arrays in our $array variable.
Here we take out the group name and group app name and then we push the name into the group in $our req_array.
foreach($array as $app){
$group = $app["group"];
$name = $app["name"];
array_push($req_array[$group], $name);
}

Related

How to convert array to multidimensional array with special keys using php?

I have an array
$array = [
0=>1
1=>Jon
2=>jon#email.com
3=>2
4=>Doe
5=>doe#email.com
6=>3
7=>Foo
8=>foo#email.com
]
What I`d like to do is to add and extra value to each value.
Something like this so I can access it when looping through the array
$array=[
0=>1[id]
1=>Jon[name]
2=>jon#email.com[email]
3=>2[id]
4=>Doe[name]
5=>doe#email.com[email]
6=>3[id]
7=>Foo[name]
8=>foo#email.com[email]
]
I guess it would be a multidimensional array?
What would be the proper way of doing it?
Loop through array and check key of items and based of it create new array and insert values in it.
$newArr = [];
foreach($array as $key=>$value){
if ($key % 3 == 0)
$newArr[] = ["id" => $value];
if ($key % 3 == 1)
$newArr[sizeof($newArr)-1]["name"] = $value;
if ($key % 3 == 2)
$newArr[sizeof($newArr)-1]["email"] = $value;
}
Check result in demo
yes just use 2 dimension array
$arr = array();
$arr[0][0] = "1"
$arr[0][1] = "Jon"
$arr[0][2] = "jon#email.com"
$arr[1][0] = "2"
$arr[1][1] = "Doe"
$arr[1][2] = "doe#email.com"
Since an array is a map in PHP, I'd recommend to use it like a map or to create a class holding the data.
$arr = array();
$arr[0]['ID'] = 1;
$arr[0]['name'] = "John";
$arr[0]['mail'] = "john#email.com;
Example for one class:
<?PHP
class User
{
public $id;
public $name;
public $mail;
function __construct($ID,$name,$mail)
{
$this->id = $ID;
$this->name = $name;
$this->mail = $mail;
}
}
?>
and then you can simply use it like that:
<?PHP
require_once("User.php");
$user = new User(1,"Mario","maio290#foo.bar");
echo $user->name;
?>
A simple, yet often-used solution is to use multidimensional array with string keys for better readability:
$array = [
0 => [
'id' => 1,
'name' => 'Jon',
'email' => 'jon#email.com',
],
1 => [
'id' => 2,
'name' => 'Doe',
'email' => 'doe#email.com',
],
2 => [
'id' => 3,
'name' => 'Foo',
'email' => 'foo#email.com',
],
];
You can loop through this like so:
for ($array as $item) {
// $item['id']
// $item['name']
// $item['email']
}
But since PHP is an object-oriented language, I'd suggest creating a class for the data-structure. This is even easier to read and you can very easily add functionality related to the entity etc.
class Person {
public $id;
public $name;
public $email;
function __construct($id, $name, $email) {
$this->id = $id;
$this->name = $name;
$this->email = $email;
}
}
$array = [
0 => new Person(1, 'Jon', 'jon#email.com'),
1 => new Person(2, 'Doe', 'doe#email.com'),
2 => new Person(3, 'Foo', 'foo#email.com'),
];
You can loop through this like so:
for ($array as $person) {
// $person->id
// $person->name
// $person->email
}
Use array_map on the result of array_chunck this way:
$array=array_map(function($val){ return array_combine(['id','name','email'],$val);}, array_chunk($array,3));
note that the second parameter of array_chunk depend of the number of columns and the first array used in array_combine too
see the working code here
You can also do like this:
$array1 = ["name"=>"alaex","class"=>4];
$array2 = ["name"=>"aley","class"=>10];
$array3 = ["student"=>$array1,"student2"=>$array2];
print_r($array3);

php - how to convert 'tree-array' to array

I have gotten the tree-array like that:
Now I want to convert it to an array like this:
array(
1 => array('id'=>'1','parentid'=>0),
2 => array('id'=>'2','parentid'=>0),
3 => array('id'=>'3','parentid'=>1),
4 => array('id'=>'4','parentid'=>1),
5 => array('id'=>'5','parentid'=>2),
6 => array('id'=>'6','parentid'=>3),
7 => array('id'=>'7','parentid'=>3)
);
I had already coded something like this:
private function _getOrderData($datas)
{
$_data = [];
static $i = 0;
foreach ($datas as $data) {
$i++;
$rows = ['id' => $data['id'], 'pid' => isset($data['children']) ? $data['id'] : 0, 'menu_order' => $i];
if(isset($data['children'])) {
$this->_getOrderData($data['children']);
}
$_data[] = $rows;
}
return $_data;
}
But it didn't work
Cry~~
How can I fix my code to get the array? Thanks~
BTW, my English is pool.
So much as I don't know you can read my description of the problem or not.
I had already solved this problem, Thx~
private function _getOrderData($datas, $parentid = 0)
{
$array = [];
foreach ($datas as $val) {
$indata = array("id" => $val["id"], "parentid" => $parentid);
$array[] = $indata;
if (isset($val["children"])) {
$children = $this->_getOrderData($val["children"], $val["id"]);
if ($children) {
$array = array_merge($array, $children);
}
}
}
return $array;
}
The array look like:
array

PHP how to keep the matched item's key with array_search and array_column?

How can I keep the matched item's key with array_search and array_column?
$items = array(
'meta-title' => [
"code" => 'meta-title'
],
'meta-keywords' => [
"code" => 'meta-keywords'
],
);
$key = array_search('meta-title', array_column($items, 'code'));
var_dump($key); // 0
The result I am after:
'meta-title'
Any ideas?
Your array_columns() call returns a numerically indexed array of strings (based on the keys from the 1st level), not the array that you're wanting to search (i.e. an array of the 'code' values from the 2nd level). You might be better off iterating through $items and building an array (key/value pairs) based on searching the arrays you're iterating through:
$items = array(
'meta-title' => [
'code' => 'meta-title'
],
'meta-keywords' => [
'code' => 'meta-keywords'
],
);
$results = array();
foreach ($items as $key => $value) {
$result = array_search('meta-title', $value);
if ($result !== false) {
array_push($results, array($key => $result));
}
}
http://sandbox.onlinephpfunctions.com/code/71934db55c67657f0336f84744e05097d00eda6d
Here is an object oriented approach that allows the column and search value to be set at run time. As a class it's more reusable and somewhat self documenting.
<?php
$items = array(
'meta-title' => [
"code" => 'meta-title'
],
'meta-keywords' => [
"code" => 'meta-keywords'
],
);
/**
* Search all records of a recordset style array for a column containing a value
* Capture the row into matches member for later use.
*/
class ColumnSearch {
private $key;
private $search;
public $matches=array();
public function __construct( $key, $search ){
$this->key = $key;
$this->search = $search;
}
public function search( array $items ){
// #todo validate $items is like a recordset
$matches = array_filter( $items, array( $this, "_filter"), ARRAY_FILTER_USE_BOTH );
$this->matches = $matches;
return count($matches);
}
private function _filter( $row, $rowKey ){
return ( $row[$this->key] == $this->search );
}
}
$search = new ColumnSearch( 'code', 'meta-title' );
$occurances = $search->search( $items );
// return value indicates how many were found, in case of multiples...
echo $occurances ." ". PHP_EOL;
// the matched row will be in matches member.
var_dump($search->matches);
// there might be more than 1, not in your example but this is very generic code.
// grab just the keys, then get the current
echo current( array_keys($search->matches) ) . PHP_EOL;
echo "New Search for value that doesn't exist.". PHP_EOL;
$newSearch = new ColumnSearch( 'code', 'title' );
$count = $newSearch->search( $items );
if( 0 == $count ){
echo "Nothing found.". PHP_EOL;
}
echo current( array_keys( $newSearch->matches) );
http://sandbox.onlinephpfunctions.com/code/83b306bfc30ef2a055cf49501bdeb5cb2e5b5ed7

creating array of objects from array of arrays, using static method call (PHP)

I have an array like this:
// Define pages
$pages = array(
"home" => array(
"title" => "Home page",
"icon" => "home"
),
"compositions" => array(
"title" => "Composition page",
"icon" => "music"
),
);
And what I am trying to accomplish is, having:
$navigation = Utils::makeNavigation($pages);
, create $navigation as an array of objects, so that I can parse it in my view
like this:
foreach($navigation as $nav_item){
echo $nav_item->page; // home(1st iter.), compositions(2nd iter.)
echo $nav_item->title;// Home page, Composition page
echo $nav_item->icon; // home, music
}
Is static Util-like-class approach good for this kind of problem?
EDIT
I came up with something like this, does this seem ok?
<?php
class Utils {
protected static $_navigation;
public static function makeNavigation($pages = array()){
if (!empty($pages)){
foreach ($pages as $page => $parts) {
$item = new stdClass;
$item->page = $page;
foreach ($parts as $key => $value) {
$item->$key = $value;
}
self::$_navigation[] = $item;
}
return self::$_navigation;
}
}
}
Assuming you are creating the array manually in your code, just cast to objects:
$pages = array(
"home" => ( object ) array(
"title" => "Home page",
"icon" => "home"
),
"compositions" => ( object ) array(
"title" => "Composition page",
"icon" => "music"
),
);
That will allow accessing them like objects:
$pages->home->title;
or looping through them like this:
for ( $pages as $pageName => $pageObject ) echo $pageName . " has title: " . $pageObject->title;
I would include the creation as a static member of the class to keep the class specific code together:
class NavItem
{
// Static member does not require an object to be called
static function create ($def)
{
$ret = array ();
foreach ($def as $idx=>$navDef)
$ret [$idx] = new NavItem ($navDef);
return $ret;
}
function __construct ($def)
{
// Do something more specific with the current def (title, icon array)
$this->param = $def;
}
function display ()
{
// Simple example
echo $this->param ['title'];
echo $this->param ['icon'];
}
var $param;
};
// Using your pages array as above
$pages = NavItem::create ($pages);
foreach ($pages as $idx=>$page)
$page->display ();

Dynamic array key in while loop

I'm trying to get this working:
I have an array that gets "deeper" every loop. I need to add a new array to the deepest "children" key there is.
while($row = mysql_fetch_assoc($res)) {
array_push($json["children"],
array(
"id" => "$x",
"name" => "Start",
"children" => array()
)
);
}
So, in a loop it would be:
array_push($json["children"] ...
array_push($json["children"][0]["children"] ...
array_push($json["children"][0]["children"][0]["children"] ...
... and so on. Any idea on how to get the key-selector dynamic like this?
$selector = "[children][0][children][0][children]";
array_push($json$selector);
$json = array();
$x = $json['children'];
while($row = mysql_fetch_assoc($res)) {
array_push($x,
array(
"id" => "$x",
"name" => "Start",
"children" => array()
)
);
$x = $x[0]['children'];
}
print_r( $json );
Hmmm - maybe better to assign by reference:
$children =& $json["children"];
while($row = mysql_fetch_assoc($res)) {
array_push($children,
array(
"id" => "$x",
"name" => "Start",
"children" => array()
)
);
$children =& $children[0]['children'];
}
$json = array();
$rows = range('a', 'c');
foreach (array_reverse($rows) as $x) {
$json = array('id' => $x, 'name' => 'start', 'children' => array($json));
}
print_r($json);
If you want to read an array via a string path, split the string in indices, and then you can do something like this to get the value
function f($arr, $indices) {
foreach ($indices as $key) {
if (!isset($arr[$key])) {
return null;
}
$arr = $arr[$key];
}
return $arr;
}

Categories