How to convert array to multidimensional array with special keys using php? - 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);

Related

Sort 2 child arrays with same keys by values of one array

I have this multidimensional array:
$value = [
'name' => ['silverado', 'civic'],
'type' => ['truck', 'car'],
];
I want to basically sort both of these child arrays by the values of name, ascending.
I have this code, which works:
$value = [
'name' => ['silverado', 'civic'],
'type' => ['truck', 'car'],
];
$name_type = [];
$columns = [];
foreach ($value['name'] as $k => $v) {
$name_type[$v] = $value['type'][$k];
}
ksort($name_type);
foreach ($name_type as $name => $type) {
$columns['name'][] = $name;
$columns['type'][] = $type;
}
$value = $columns;
I'm just curious if there is a better way of coding this rather than using 2 foreach loops.
You can use array_multisort, check Demo
array_multisort($value["name"],$value["type"]);

how to insert 2 arrays with createmany in laravel

i have a relationship that i try to insert with the relationship into the model every thing is fine when i just add phone numbers but when i add the secound field which is type_id i cant handle it because it wont insert the secound field into table here is how i do it in my controller store i want my user to be able to send unlimited phone numbers and each of them have a type_id how can i achive that
:
public function store(StoreHome $request)
{
$validated = $request->all();
if (!$validated) {
return $this->sendError('Validation Error.', $validated->errors());
}
$home = Home::create($validated);
$phones = [];
$type_id = [];
$numbers = $request->input('phones');
$type_id = $request->input('type_id');
foreach($numbers as $number => $item){
$phones[] = [
'phone' => $number
];
$types[] = [
$type_id[] = [
'type_id' => $type_id[$item]
]
];
}
$home->phones()->createMany($phones);
return new HomeResource($home);
You pass $phones to createMany, this variable does not contain any type_id because you put them into $types variable which, moreover is not declared (I suppose you mispelled $type_id = []; instead of $types = [];
Example solution;
$datas = [];
foreach($numbers as $number => $item){
array_push($datas, [$number => $type_id[$item]]);
}
foreach ($datas as $key => $value) {
Home::create([
'phone' => $key,
'type_id' => $value
]);
}

Loop over one array as if it was a multidimensional array

I have an array like:
$array = array(
'name' => 'Humphrey',
'email' => 'humphrey#wilkins.com
);
This is retrieved through a function that gets from the database. If there is more than one result retrieved, it looks like:
$array = array(
[0] => array(
'name' => 'Humphrey1',
'email' => 'humphrey1#wilkins.com'
),
[1] => array(
'name' => 'Humphrey2',
'email' => 'humphrey2#wilkins.com'
)
);
If the second is returned, I can do a simple foreach($array as $key => $person), but if there is only one result returned (the first example), I can't run a foreach on this as I need to access like: $person['name'] within the foreach loop.
Is there any way to make the one result believe its a multidimensional array?
Try this :
if(!is_array($array[0])) {
$new_array[] = $array;
$array = $new_array;
}
I would highly recommended making your data's structure the same regardless of how many elements are returned. It will help log terms and this will have to be done anywhere that function is called which seems like a waste.
You can check if a key exists and do some logic based on that condition.
if(array_key_exists("name", $array){
//There is one result
$array['name']; //...
} else {
//More then one
foreach($array as $k => $v){
//Do logic
}
}
You will have the keys in the first instance in the second yours keys would be the index.
Based on this, try:
function isAssoc(array $arr)
{
if (array() === $arr) return false;
return array_keys($arr) !== range(0, count($arr) - 1);
}
if(isAssoc($array)){
$array[] = $array;
}
First check if the array key 'name' exists in the given array.
If it does, then it isn't a multi-dimensional array.
Here's how you can make it multi-dimensional:
if(array_key_exists("name",$array))
{
$array = array($array);
}
Now you can loop through the array assuming it's a multidimensional array.
foreach($array as $key => $person)
{
$name = $person['name'];
echo $name;
}
The reason of this is probably because you use either fetch() or fetchAll() on your db. Anyway there are solutions that uses some tricks like:
$arr = !is_array($arr[0]) ? $arr : $arr[0];
or
is_array($arr[0]) && ($arr = $arr[0]);
but there is other option with array_walk_recursive()
$array = array(
array(
'name' => 'Humphrey1',
'email' => 'humphrey1#wilkins.com'
),
array(
'name' => 'Humphrey2',
'email' => 'humphrey2#wilkins.com'
)
);
$array2 = array(
'name' => 'Humphrey2',
'email' => 'humphrey2#wilkins.com'
);
$print = function ($item, $key) {
echo $key . $item .'<br>';
};
array_walk_recursive($array, $print);
array_walk_recursive($array2, $print);

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

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

Get value from multiple dimension associative array in Php

I have a POST request array that looks like this
$request = array (size=2)
'licence' => string 'uDyQwFwqV7aQG2z' (length=15)
'user' =>
array (size=7)
'first_name' => string 'Danut' (length=5)
'last_name' => string 'Florian' (length=7)
'username' => string 'daniesy9' (length=8)
'password' => string '123456' (length=6)
'rpassword' => string '123456' (length=6)
'email' => string 'daniesy+1#me.com' (length=16)
'phone' => string '9903131' (length=7)
This in fact is an array which represents values sent by a form. I know the name of the elements, for example the username input has the name of user[username] and i have to find the related value from the array, by name. Something like:
$key = "user[username]";
$request[key];
Any idea how to do this?
I know that the correct way to do it is $request["user"]["username"] but it's quite complicated because i have to use the fields names from the form which are user[username], user[firstname], etc and it might have up to 4 levels of depth.
Answered in comments but similar Question to
Convert a String to Variable
eval('$username = $request["user"]["username"];');
Edit
Eval not a valid suggestion as request data.
So I would suggest the second method on this post
<?php
$request = array(
'user' => array(
'username' => 'joe_blogs'
)
);
function extract_data($string) {
global $request;
$found_matches = preg_match_all('/\[\"([a-z]+)\"\]/', $string, $matches);
if (!$found_matches) {
return null;
}
$current_data = $request;
foreach ($matches[1] as $name) {
if (key_exists($name, $current_data)) {
$current_data = $current_data[$name];
} else {
return null;
}
}
return $current_data;
}
$username = extract_data('request["user"]["username"]');
?>
function findInDepth($keys, $array){
$key = array_shift($keys);
if(!isset($array[$key])){
return FALSE;
}
if(is_array($array[$key])){
return findInDepth($keys, $array[$key]);
}
return $array[$key];
}
$key = "user[username]";
$keys = preg_split("/(\[|\])/", $key);
echo findInDepth($keys, $request);
This function solves my problem. It first splits the string (aka the input name) into an array of keys and then recessively searches in depth the array by keys until it finds a value which is not an array and returns FALSE otherwise.
You could separate keys with dots. Primitive example:
<?php
class ArrayDot
{
protected $array = [];
public function __construct(array $array) {$this->array = $array;}
public function get($path)
{
$array = $this->array;
foreach(explode('.', $path) as $key) {
$array = $array[$key];
}
return $array;
}
}
$array = [
'user' => [
'username' => 'tootski',
]
];
$a = new ArrayDot($array);
echo $a->get('user.username'); # tootski

Categories