manipulate, delete or unset subarray of a multidimensional array [duplicate] - php

This question already has answers here:
How to extract specific array keys and values to another array?
(2 answers)
Closed 4 months ago.
I need help manipulating my two dimensional array. My array has many record sets with 2 columns of values and I'd like to manipulate the array so there is an array of many record sets with one column by converting one of my original columns as the key to the one column of values.
My Array:
[0]=>
[0]=> "48903"
[1]=> "SDFI"
[1]=>
[0]=> "2890"
[1]=> "DISL"
[2] =>
[0]=> "80890"
[1]=> "DISL"
...plus more
Intended array:
[0]=>
[48903]= "SDFI"
[2890]=>"DISL"
[80890] => "DISL"
...plus more
I've tried creating a new array with the intended keys and then unsetting the subarray but when the new array is vardumped at the end of script, it still shows that they subarray hasn't been removed.
my experimental codes
$newarr=array();
foreach($arr as $val => $rename){
$newarr[$rename[0]]= $rename;
}
foreach($newarr as $k => $v){
unset($v[0]); //does not remove/unset the extra column when newarr is var_dumped at the end of the script
$filter = array_filter($newarr, function($k) {
return $k == '1'; }); //or return $k !== 0; }) // other code to filter extra column that does not seem to work.
I think I came across a similar problem from someone else but they had 3 columns for each record set and wanted to reduce the number of columns to 2 and change the extra column as a key. However, I can't seem to locate that page. If anyone could find it and post a link, that would be great.
Any help would be great.. thank you in advance.

Try this:
<?php
// the function:
function arr2kv($arr) {
$res = array();
foreach($arr as $v) $res[$v[0]] = $v[1];
return $res;
}
// testing:
$n = array(
array("48903","SDFI"),
array("2890","DISL"),
array("80890","DISL")
);
print_r( arr2kv($n) );
/* // result:
Array
(
[48903] => SDFI
[2890] => DISL
[80890] => DISL
)
*/

Try this -
$newarr=array();
foreach($arr as $val => $rename){
$newarr[$rename[0]]= $rename[1];
}

Related

How to get element from array?

How to get single element from this?
array(1) { [0]=> object(stdClass)#3 (2) { ["id"]=> int(29595) ["image_id"]=> string(20) "eohsidatfx8wyw5ltzt6" } }
I need to separate "image_id". How to do it? I tried
echo $result["image_id"]
but it doesn't work:
Notice: Undefined index: image_id in C:\xampp\htdocs\IGDB\moje\index.php on line 53
It seems your array only directly contains object(stdClass)#3. This object is itself an array containing id and image_id. You can access image_id by doing
echo $result[0]["image_id"];
Ok, got it.
$result3=array_column($result2, 'image_id');
echo $result3[0];
$myArray = array(
'#3' => array (
"id"=> 29595,
"image_id"=> "eohsidatfx8wyw5ltzt6"
)
);
what you are looking for is in the second level of your array.
Use a foreach loop to iterate of the arrays key/value pairs.
foreach($myArray as $value){
foreach($value as $key => $id){
if($key === 'image_id'){
$output = $id;// output now holds the vlaue of the key set with 'image_id'
}
}
}
If you know the value of the key, you can also access this by using the keys like so: $arrayname['firstlevelkey']['secondlevelkey'];
Notice: Undefined index: image_id in C:\xampp\htdocs\IGDB\moje\index.php on line 53
--> This is because you are defining an array with a key that does not exist in the array
echo $result["image_id"] --> here you are telling php that "image_id" is on the first level of the array, however, it looks to be nested in the second layer of the array you are trying to parse. $result['#3']['image_id'].
If you are not sure, write a conditional that looks in the first array using is_array(), if the first is a key value holding a child array. Then run the foreach loop again to look for the key/pair value.
foreach($arr as $values){
// do something if value is string
if(is_array($values){
foreach($values as $key => $value){
// check your second level $key/$value
}
}
}

Create multidimensional array from a loop in PHP

I'm trying to create a multidimensional array from some content I have in a database.
At the moment, I have this, which creates an array:
$js_arr = [];
while($row = mysqli_fetch_array($r->query)){
$js_arr[] = $row['todo_content'];
}
Returning:
Array ( [0] => first [1] => tester [2] => first item [3] => Hello!)
However, I also need to grab the $row['todo_id'].
I've tried this, but it only creates an array for the first row:
$js_arr = [];
while($row = mysqli_fetch_array($r->query)){
$js_arr['todo_content'] = $row['todo_content'];
$js_arr['todo_id'] = $row['todo_id'];
}
Returning:
array(2) { ["todo_content"]=> string(3) "hey" ["todo_id"]=> string(2) "90" }
I'm still learning PHP so any help or pointers would be much appreciated.
Two good options:
If the todo_id is unique, let it be the key:
$js_arr[$row['todo_id']] = $row['todo_content'];
Or for a multi-dimensional array, needed if you have more than just todo_content:
$js_arr[] = array('todo_content' => $row['todo_content'], 'todo_id' => $row['todo_id']);
Simply nest the items you want inside an array:
$js_arr[] = [
'todo_content' => $row['todo_content'],
'todo_id' => $row['todo_id']
];
The $js_arr[] part cannot ever be anything else, because any other syntax will not unconditionally add an element to the end of your multidimensional array.
I would use the ID as the key:
while($row = mysqli_fetch_array($r->query)){
$js_arr[$row['todo_id']]['todo_content'] = $row['todo_content'];
}
Or - assuming you need everything that you get from the database:
while($row = mysqli_fetch_array($r->query)){
$js_arr[$row['todo_id']] = $row;
}
What you can replace with (no loop, but no ID's as keys):
$js_arr = mysqli_fetch_all($r->query);

PHP - Nested associative array in a $_SESSION array [duplicate]

This question already has answers here:
Array as session variable
(4 answers)
Closed 9 years ago.
I was wondering is it possible to have an associative array within a session array? If so, what would be the best way to do it and how can I loop through it? I have tried the following but it doesnt seem to work:
//The variables are post variables from a form
$_SESSION['users'][$id] = array('name'=>$name, 'status'=>$status, 'salary'=>"20000");
Here is how I am trying to loop through the session array:
foreach ($_SESSION['users'] as $id=>$value) {
echo $value;
}
Also, If I knew an id how can I get the name? Can I do $_SESSION['users']['1234']['name']?
Yes you can have an associative array within a session array. You can also loop through it with a for or a foreach loop. e.g.:
$array = $_SESSION['users'][$id];
foreach($array as $key => $value) {
var_dump($array[$key]); //Will dump info about a single element
}
However, it would be helpful to see your error message or additional details of what you are trying to do and what about it that isn't working.
EDIT
Based on your updated question, since you are accessing and array of arrays (theoretically) you would need to nest a foreach with another foreach to get at your values.
foreach($_SESSION['users'] as $arrays) {
foreach($arrays as $arrKey => $arrVal) {
var_dump($arrays[$arrKey]);
}
}
Running that on your data would output (with my own fake data to fill variables):
string(7) "johndoe"
string(6) "active"
string(5) "20000"

php - push array into an array -(pushing both key and the array)

I am trying to add an array to an existing array. I am able to add the array using the array_push . The only problem is that when trying to add array that contains an array keys, it adds an extra array within the existing array.
It might be best if I show to you
foreach ($fields as $f)
{
if ($f == 'Thumbnail')
{
$thumnail = array('Thumbnail' => Assets::getProductThumbnail($row['id'] );
array_push($newrow, $thumnail);
}
else
{
$newrow[$f] = $row[$f];
}
}
The fields array above is part of an array that has been dynamically fed from an SQl query it is then fed into a new array called $newrow. However, to this $newrow array, I need to add the thumbnail array fields .
Below is the output ( using var_dump) from the above code. The only problem with the code is that I don't want to create a seperate array within the arrays. I just need it to be added to the array.
array(4) { ["Product ID"]=> string(7) "1007520"
["SKU"]=> string(5) "G1505"
["Name"]=> string(22) "150mm Oval Scale Ruler"
array(1) { ["Thumbnail"]=> string(77) "thumbnails/products/5036228.jpg" } }
I would really appreciate any advice.
All you really want is:
$newrow['Thumbnail'] = Assets::getProductThumbnail($row['id']);
You can use array_merge function
$newrow = array_merge($newrow, $thumnail);
Alternatively, you can also assign it directly to $newrow:
if ($f == 'Thumbnail')
$newrow[$f] = Assets::getProductThumbnail($row['id']);
else
...
Or if you want your code to be shorter:
foreach($fields as $f)
$newrow[$f] = ($f == 'Thumbnail')? Assets::getProductThumbnail($row['id']) : $row[$f];
But if you're getting paid by number of lines in your code, don't do this, stay on your code :) j/k

How to convert an array of arrays or objects to an associative array?

I'm used to perl's map() function where the callback can assign both the key and the value, thus creating an associative array where the input was a flat array. I'm aware of array_fill_keys() which can be useful if all you want to do is create a dictionary-style hash, but what if you don't necessarily want all values to be the same? Obviously all things can be done with foreach iteration, but what other (possibly more elegant) methods exist?
Edit: adding an example to clarify the transformation. Please don't get hung up on the transformation, the question is about transforming a flat list to a hash where we can't assume that all the values will be the same.
$original_array: ('a', 'b', 'c', 'd')
$new_hash: ('a'=>'yes', 'b'=>'no', 'c'=>'yes', 'd'=>'no')
*note: the values in this example are arbitrary, governed by some business logic that is not really relevant to this question. For example, perhaps it's based on the even-oddness of the ordinal value of the key
Real-world Example
So, using an answer that was provided here, here is how you could parse through the $_POST to get a list of only those input fields that match a given criteria. This could be useful, for example, if you have a lot of input fields in your form, but a certain group of them must be processed together.
In this case I have a number of input fields that represent mappings to a database. Each of the input fields looks like this:
<input name="field-user_email" value="2" /> where each of this type of field is prefixed with "field-".
what we want to do is, first, get a list of only those input fields who actually start with "field-", then we want to create an associative array called $mapped_fields that has the extracted field name as the key and the actual input field's value as the value.
$mapped_fields = array_reduce( preg_grep( '/field-.+/', array_keys( $_POST ) ), function( $hash, $field ){ $hash[substr( $field, 6 )] = $_POST[$field]; return $hash; } );
Which outputs:
Array ( [date_of_birth] => 1 [user_email] => 2 [last_name] => 3 [first_name] => 4 [current_position] => 6 )
(So, just to forestall the naysayers, let me agree that this bit of compact code is arguably a lot less readable that a simple loop that iterates through $_POST and, for each key, checks to see if it has the prefix, and if so, pops it and its value onto an array)
I had the exact same problem some days ago. It is not possible using array_map, but array_reduce does the trick.
$arr = array('a','b','c','d');
$assoc_arr = array_reduce($arr, function ($result, $item) {
$result[$item] = (($item == 'a') || ($item == 'c')) ? 'yes' : 'no';
return $result;
}, array());
var_dump($assoc_arr);
result:
array(4) { ["a"]=> string(3) "yes" ["b"]=> string(2) "no" ["c"]=> string(3) "yes" ["d"]=> string(2) "no" }
As far as I know, it is completely impossible in one expression, so you may as well use a foreach loop, à la
$new_hash = array();
foreach($original_array as $item) {
$new_hash[$item] = 'something';
}
If you need it in one expression, go ahead and make a function:
function array_map_keys($callback, $array) {
$result = array();
foreach($array as $item) {
$r = $callback($item);
$result[$r[0]] = $r[1];
}
return $result;
}
This is a clarification on my comment in the accepted method. Hopefully easier to read. This is from a WordPress class, thus the $wpdb reference to write data:
class SLPlus_Locations {
private $dbFields = array('name','address','city');
public function MakePersistent() {
global $wpdb;
$dataArray = array_reduce($this->dbFields,array($this,'mapPropertyToField'));
$wpdb->insert('wp_store_locator',$dataArray);
}
private function mapPropertyToField($result,$property) {
$result[$property] = $this->$property;
return $result;
}
}
Obviously there is a bit more to the complete solution, but the parts relevant to array_reduce() are present. Easier to read and more elegant than a foreach or forcing the issue through array_map() plus a custom insert statement.
Nice!
A good use case of yield operator!
$arr = array('a','b','c','d');
$fct = function(array $items) {
foreach($items as $letter)
{
yield sprintf("key-%s",
$letter
) => "yes";
}
};
$newArr = iterator_to_array($fct($arr));
which gives:
array(4) {
'key-a' =>
string(3) "yes"
'key-b' =>
string(3) "yes"
'key-c' =>
string(3) "yes"
'key-d' =>
string(3) "yes"
}

Categories