Convert a multidimensional array (php) [duplicate] - php

This question already has answers here:
Generate an associative array from an array of rows using one column as keys and another column as values
(3 answers)
Closed 3 years ago.
im currently struggling with converting this array in PHP to a more simplified one. This is my array to start with stored in $array:
[0] => Array
(
[name] => name-1
[value] => xXX
)
[1] => Array
(
[name] => name-2
[value] => YYY
)
I would like to transfrom this array to this simplified one $array_new:
[0] => Array
(
[name-1] => xXX
)
[1] => Array
(
[name-2] => YYY
)
I sadly don't know were to start... Could somebody help me out?
Edit: After I converted the array via array_column() oder foreach loop I still cant get the right data with $array_new['name-2'];

You can use array-column to do that. The documentation said:
array_column ( array $input , mixed $column_key [, mixed $index_key = NULL ] ) : array
So do:
$first_names = array_column($array, 'value', 'name');
Live example: 3v4l

Question
Alright, this is a question I see a lot of beginners deal with.
Just be a little creative:
Answer
//Let's get your old array:
$old = [
0 => [
'name' => 'name-1',
'value' => 'xXX'
],
1 => [
'name' => 'name-2',
'value' => 'YYY'
]
];
//Let's create an array where we will store the new data:
$result = [];
foreach($old as $new) { //Loop through
$result[$new['name']] = $new['value']; //Store associatively with value as value
}
var_dump($result);
Result:
Array[2] => [
[name-1] => xXX,
[name-2] => YYY
];

Using a foreach:
<?php
$items =
[
[
'plant' => 'fern',
'colour' => 'green'
],
[
'plant' => 'juniper',
'colour' => 'blue'
]
];
foreach($items as $item) {
$output[][$item['plant']]=$item['colour'];
}
var_dump($output);
Output:
array(2) {
[0]=>
array(1) {
["fern"]=>
string(5) "green"
}
[1]=>
array(1) {
["juniper"]=>
string(4) "blue"
}
}

Related

How to remove specific element from array in php

I have the following array
Array
(
[tags] => Array
(
[0] => hello
)
[assignee] => 60b6a8a38cf91900695dd46b
[multiple_assignee] => Array
(
[0] => Array
(
[accountId] => 60b6a8a38cf91900695dd46b
)
[1] => Array
(
[accountId] => 5b39d23d32e26a2de15f174f
)
)
)
I want to remove 60b6a8a38cf91900695dd46b from the multiple_assignee array.
I have tried with the following code:
if (($key = array_search($this->getUsersHashMapValue($responsiblePartyIds[0]), $mutipleAssignee)) !== false) {
unset($mutipleAssignee[$key]['accountId']);
}
But it is not removing that element. The intention is I don't want to repeat the 60b6a8a38cf91900695dd46b assignee in the multiple assignee array.
I have also tried with the following code:
foreach($mutipleAssignee as $subKey => $subArray){
if($subArray['accountId'] == $this->getUsersHashMapValue($responsiblePartyIds[0])){
unset($mutipleAssignee[$subKey]);
}
}
But it is resulting as
Array
(
[tags] => Array
(
[0] => hello
)
[assignee] => 60b6a8a38cf91900695dd46b
[multiple_assignee] => Array
(
[1] => Array
(
[accountId] => 5b39d23d32e26a2de15f174f
)
)
)
rather than
[multiple_assignee] => Array
(
[0] => Array
(
[accountId] => 5b39d23d32e26a2de15f174f
)
)
Thank you
Just extract the accountId column and search that. Then use that key:
$key = array_search($this->getUsersHashMapValue($responsiblePartyIds[0]),
array_column($mutipleAssignee, 'accountId'));
unset($mutipleAssignee[$key]);
After your edit it seems you just want to reindex the subarray after unset:
$mutipleAssignee = array_values($mutipleAssignee);
I would just use a simple for loop. All of the array_* functions are really helpful but I find that they hide nuances. Since I don't have your functions I'm just making a plain-old one, but you should be able to port this.
$data = [
'tags' => [
'hello',
],
'assignee' => '60b6a8a38cf91900695dd46b',
'multiple_assignee' => [
[
'accountId' => '60b6a8a38cf91900695dd46b',
],
[
'accountId' => '5b39d23d32e26a2de15f174f',
],
],
];
$assignee = $data['assignee'];
foreach ($data['multiple_assignee'] as $multiple_assignee_key => $multiple_assignee) {
// if the root assignee is also listed in the multiple assignee area
if ($multiple_assignee['accountId'] === $assignee) {
// remove the duplicate from the multiple area
unset($data['multiple_assignee'][$multiple_assignee_key]);
// re-index the array
$data['multiple_assignee'] = array_values($data['multiple_assignee']);
}
}
This outputs:
array(3) {
["tags"]=>
array(1) {
[0]=>
string(5) "hello"
}
["assignee"]=>
string(24) "60b6a8a38cf91900695dd46b"
["multiple_assignee"]=>
array(1) {
[0]=>
array(1) {
["accountId"]=>
string(24) "5b39d23d32e26a2de15f174f"
}
}
}
Demo here: https://3v4l.org/tYppK

Flatten array to use array_key_exists on a multi-dimensional array

I have a php array that looks like this...
(
[name] => Test
[age] => 50
[items] => Array
(
[23456] => Array
(
[id] => 12
)
[3345] => Array
(
[id] => 344
[status] => stock
)
[2236] => Array
(
[id] => 876
)
)
)
I am trying to search for any mention of status in the items section of the array.
I have tried using array_key_exists like this...
array_key_exists('test',$arr);
But this is giving me false, as an alternative I was thinking of flattening the array somehow and then searching to make it work with my array.
Is this the best choice?
You can use also use array_column() to see if the key exists :
$exist = !empty(array_column($arr['items'], 'status'));
But, #Barmar answer could be more efficient on large arrays.
Loop over the items array and check each item.
function status_exists_in_items($arr) {
foreach ($arr['items'] as $item) {
if (array_key_exists('status', $item)) {
return true;
}
}
return false;
}
Just filter the array and handle just those items, that have a status key.
$data = [
'name' => 'Test',
'age' => 50,
'items' => [
23456 => [
'id' => 12,
],
3345 => [
'id' => 344,
'status' => 'stock',
],
2236 => [
'id' => 876,
],
],
];
$result = array_filter($data['items'], function($item) {
if (isset($item['status'])) return $item;
});
var_dump($result);
Results into:
array(1) {
[3345] => array(2) {
["id"] => int(344)
["status"] => string(5) "stock"
}
}
This solution could be slow (as every function that handles native arrays) depending on how big your array is. You can work with filter iterators, which work as yields and do not consume as much memory as arrays do.

How to flip Multidimensional array in PHP using array_flip

I have Multidimensional array with key value pair so I want to flip i.e key gets to value place and values get to key place but I am getting error
My Php code is:
echo '<pre>',print_r($res),'</pre>';
output when print_r($res):
Array
(
[0] => Array
(
[userid] => 1
)
[1] => Array
(
[userid] => 2
)
[2] => Array
(
[userid] => 3
)
)
getting error in output when want to flip this array:
array_flip(): Can only flip STRING and INTEGER values!
How to solve this?
You are trying to flip a multidimensional array where each value is an array, but according to the docs of array_flip:
Note that the values of array need to be valid keys, i.e. they need to
be either integer or string. A warning will be emitted if a value has
the wrong type, and the key/value pair in question will not be
included in the result.
You could use array_map to use array_flip on each entry:
$a = [
["userid" => 1],
["userid" => 2],
["userid" => 3],
];
$a = array_map("array_flip", $a);
print_r($a);
Result
Array
(
[0] => Array
(
[1] => userid
)
[1] => Array
(
[2] => userid
)
[2] => Array
(
[3] => userid
)
)
See a php demo
array_flip() does not flip array as values. array_flip() can only flip string and integer values.
You can try this:
$arr = [
[ 'userid' => 1 ],
[ 'userid' => 2 ],
[ 'userid' => 3 ]
];
foreach($arr as $a){
$flipped[] = array_flip($a);
}
print_r($flipped);
You can try the following way
$arr = [
[ 'userid' => 1, ],
[ 'userid' => 2, ],
[ 'userid' => 3, ]
];
array_walk($arr, function(&$val) { $val = array_flip($val); });

Count the keys of multi-dimension array php

Maybe the title can not explain my question ,please see my example :
I have an multi-dimension array like this :
Array
(
[0] => Array
(
[name] => 'A'
[ec_dest_name] => 楽天testuser_998
),
[1] => Array
(
[name] => 'A'
[ec_dest_name] => 楽天testuser_998
),
[2] => Array
(
[name] => 'B'
[ec_dest_name] => 楽天testuser_998
),
[3] => Array
(
[name] => 'C'
[ec_dest_name] => 楽天testuser_998
)
)
I want to count the element by key name , it mean that I want to return an array like :
Array ('A' => 2 , 'B'=>1, 'C'=>1)
Any quick way to accomplish that , I could loop array and count but I think it is not a good idea
Thank in advanced
You can use array_count_values & array_column togather -
$counts = array_count_values(array_column($your_array, 'name'));
Output
array(3) {
["A"]=>
int(2)
["B"]=>
int(1)
["C"]=>
int(1)
}
Demo
As Mark Baker suggested for older PHP versions -
$counts = array_count_values(
array_map(function($value) {
return $value['name'];
}, $your_array)
);
You may as well do that with 2 Loops as shown below. You might test this also HERE.
<?php
$arrSections = array();
$arrCounts = array();
$arrMain = array(
array(
'name' => "A",
'ec_dest_name' => "楽天testuser_998",
),
array(
'name' => "A",
'ec_dest_name' => "楽天testuser_998",
),
array(
'name' => "B",
'ec_dest_name' => "楽天testuser_998",
),
array(
'name' => "C",
'ec_dest_name' => "楽天testuser_998",
),
);
// BUNDLE ARRAYS WITH SIMILAR name INTO ONE GROUP
// THUS CREATING A MULTI-DIMENSIONAL ARRAY WHOSE MAIN KEYS CORRESPOND TO
// THE name OF THE MEMBER ARRAYS IN THE GROUP.
foreach($arrMain as $iKey=>$subMain){
$name = $subMain['name'];
if(!array_key_exists($name, $arrSections)) {
$arrSections[$name] = array();
}
$arrSections[$name][] = $subMain;
}
// FETCH THE COUNTS OF EACH GROUP AND MAKE AN ARRAY OUT OF IT...
foreach($arrSections as $k=>$v){
$arrCounts[$k] = count($v);
}
var_dump($arrCounts);
//OUTPUTS::
array (size=3)
'A' => int 2
'B' => int 1
'C' => int 1

Get column content as array key [duplicate]

This question already has answers here:
Generate an associative array from an array of rows using one column as keys and another column as values
(3 answers)
Closed 7 months ago.
I am rewrting a newsletter-thingy.
I have a table for all newsletter fields, that is like this:
field_uid | field_name | field_content | field_letter_id
Where f.x. the column field_name can have the value letter_headline
and the column field_content can have the value My headline.
When I do this:
$fields = $this->db->dbh->query("SELECT field_name, field_content FROM newsletter_fields WHERE field_letter_uid = '". $letter_id ."'");
foreach($fields->fetchAll(PDO::FETCH_ASSOC) as $key) {
print_r($key);
}
It will correctly give me this:
Array ( [field_name] => letter_image0 [field_content] => image.jpg )
Array ( [field_name] => letter_headline [field_content] => My headline )
Array ( [field_name] => letter_headline_size [field_content] => 12 )
Array ( [field_name] => letter_sub_headline [field_content] => My subheadline )
Array ( [field_name] => letter_sub_headline_size [field_content] => 10 )
Array ( [field_name] => letter_content [field_content] => Letter content )
Array ( [field_name] => letter_link [field_content] => www.example.com )
Array ( [field_name] => letter_link_txt [field_content] => Example )
What I want is to build an array like this
$field["letter_image"] = "image.jpg";
$field["letter_headline"] = "My headline"
And then I can output the content with:
echo $field["letter_image"];
But I can't seem to figure out how to set the field array.
$result = array_combine(array_column($data, 'field_name'), $data);
This is an old question, but I think it is worth mentioning that [array_column][1] function can accept the name of the column to use as array keys as a third parameter, so the easiest solution for this is :
// field_content column will be used as values of the array
// field_name column will be used as keys
$result = array_column($data, 'field_content', 'field_name');
Applying this to the example of #Toskan's answer:
$x = [['id' => 5, 'name' => 'john'], ['id' => 15, 'name' => 'jim']];
$result = array_column($x, 'name', 'id');
print_r($result);
// outputs Array ( [5] => john [15] => jim )
Easiest solution is just iterate through your array, like:
$result = [];
foreach($data as $row)
{
$result[$row['field_name']] = $row['field_content'];
}
You'll probably want to do this in your fetch cycle (so you'll avoid then iterating through rows twice)
well, almas solution is not using the native implementation that is optimized.
I am not saying it is wrong, just not optimized.
This should be optimized:
$x = [['id' => 5, 'name' => 'john'], ['id' => 15, 'name' => 'jim']];
$keys = array_column($x, 'id');
$values = array_column($x, 'name');
$result = array_combine($keys, $values);
var_dump($result);
//outputs array(2) { [5]=> string(4) "john" [15]=> string(3) "jim" }
This does not work with PHP 4 and only works php > 5.5
Use the third parameter of array_column
$rows = [
[
'field_name' => 'letter_image',
'field_content' => 'image.jpg'
],
[
'field_name' => 'letter_headline',
'field_content' => 'My headline'
],
];
$fields = array_column($rows, 'field_content', 'field_name');
---
php > var_dump($fields);
array(2) {
["letter_image"]=> string(9) "image.jpg"
["letter_headline"]=> string(11) "My headline"
}
https://www.php.net/manual/es/function.array-column.php
Garh... Nevermind..
Fairly simple
$field[$key["field_name"]] = $key["field_content"];

Categories