Reformat a simple PHP array - php

How do I go about reformatting an object?
Array
(
[0] => Array
(
[user_id] => 5
[first_name] => Ace
[last_name] => Black
)
[1] => Array
(
[user_id] => 6
[first_name] => Gary
[last_name] => Surname
)
[2] => Array
(
[user_id] => 7
[first_name] => Alan
[last_name] => Person
)
)
I need to reformat this so the user_id name is changed to just 'id' and the first_name and last_name values are merged into a single value called 'name' so the final result would look like:
Array
(
[0] => Array
(
[id] => 5
[name] => Ace Black
)
)

You might find array_map useful for this
function fixelement($e)
{
//build new element from old
$n=array();
$n['id']=$e['user_id'];
$n['name']=$e['first_name'].' '.$e['last_name'];
//return value will be placed into array
return $n;
}
$reformatted = array_map("fixelement", $original);
As you can see, one downside is that this approach constructs a second copy of the array, but having written the callback, you can always use it 'in place' like this:
foreach($original as $key=>$value)
{
$original[$key]=fixelement($value);
}

If you want to do it in place:
Foreach that array, set the keys to the values you want, unset the keys for the values you no longer want.
If you want a copy of it:
Foreach that array and ETL (extract, transform, load) into another similar array.
If you need further details to help let me know.

Related

Remove related element from multidimensional array in php

I have an array of image data like this:
[other-image] => Array
(
[img] => Array
(
[0] => 1526973657.jpg
[1] => 1526973661.jpg
[2] => 1526973665.jpg
)
[path] => Array
(
[0] => ../post-upload/1/
[1] => ../post-upload/1/
[2] => ../post-upload/1/
)
[type] => Array
(
[0] => 1
[1] => 1
[2] => 1
)
[thumb] => Array
(
[0] => thumb_1526973661.jpg
[1] => thumb_1526973665.jpg
[2] => thumb_1526973668.jpg
)
)
Now I want to delete an image and it's all related data from sub arrays. (path, type, thumb data)
This is how I tried it in php:
$delkey = '1526973657.jpg';
if(in_array($delkey, $_SESSION['other-image']['img'])){
$imgkey = array_search($delkey, $_SESSION['other-image']['img']);
if($imgkey) unset($_SESSION['other-image']['img'][$imgkey]);
}
But problem is I can't delete related data from other arrays.
Can anybody tell me how to do this?
Thank you.
You should use !==false after array_search() because it may return first index i.e. 0 in some cases, so your condition will not executed. And regarding delete related data from other arrays, you have to unset other data related to that key.
if($imgkey!==false){
unset($_SESSION['other-image']['img'][$imgkey]);
unset($_SESSION['other-image']['path'][$imgkey]);
unset($_SESSION['other-image']['type'][$imgkey]);
unset($_SESSION['other-image']['thumb'][$imgkey]);
}
Is the related data has same key with img?
If they are same, I think you only need to add some codes to delete other data like the way was used to delete img.
if($imgkey) unset($_SESSION['other-image']['path'][$imgkey]);
if($imgkey) unset($_SESSION['other-image']['type'][$imgkey]);
if($imgkey) unset($_SESSION['other-image']['thumb'][$imgkey]);
If the keys in img sub-array are related with the same key(index) in sub-arrays(path, type and thumb, you can also unset those keys. e.g.
$delkey = '1526973657.jpg';
if(in_array($delkey, $_SESSION['other-image']['img'])){
$imgkey = array_search($delkey, $_SESSION['other-image']['img']);
if($imgkey){
unset($_SESSION['other-image']['img'][$imgkey]);
unset($_SESSION['other-image']['path'][$imgkey]);
unset($_SESSION['other-image']['type'][$imgkey]);
unset($_SESSION['other-image']['thumb'][$imgkey]);
}
}

checking condition in multi dimensional array

I want to check a multi dimensional array for a key value and print its parent array's another key value. This might confuse a bit. But the below example can make it clear. I have a array like this.
Entity Response : Array
(
[0] => Array
(
[type] => FieldTerminology
[relevance] => 0.709023
[count] => 4
[text] => domain name
)
[1] => Array
(
[type] => Company
[relevance] => 0.603375
[count] => 2
[text] => Laravel
)
[2] => Array
(
[type] => Person
[relevance] => 0.548389
[count] => 1
[text] => M. Naveen Kumar
)
I want to check if any array has a key [type] and its value = "Person" , then i want to get its value of the key[text]. In this case I want to print M. Naveen Kumar
You can traverse the array to find it. you can use foreach(), array_walk() and so on.
$o = [];
array_walk($array, function($v) useļ¼ˆ&$o){$v['type'] == 'Person' ? $o[] = $v['text'] : '';});
var_dump($o);
Try this
$people = array_filter($array, function($each) { return $each['type'] == 'Person'; });
$names = array_map(function($each) { return $each['name']; }, $people);
How does this work step by step?
Filter the array by type using array_filter
Then map to names using array_map

Setting an array item's value as the parent array's key (PHP) [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 have an array of array that looks like this:
Array
(
[0] => Array
(
[id] => I100
[name] => Mary
[gender] => F
)
[1] => Array
(
[id] => I101
[name] => John
[gender] => M
)
[2] => Array
(
[id] => I245
[name] => Sarah
[gender] => F
)
)
I want to set the key of the parent array with the value of id, so the result array looks like this:
Array
(
[I100] => Array
(
[id] => I100
[name] => Mary
[gender] => F
)
[I101] => Array
(
[id] => I101
[name] => John
[gender] => M
)
[I245] => Array
(
[id] => I245
[name] => Sarah
[gender] => F
)
)
If possible I'd like to avoid using an additional loop to go through the array and creating a new array to store each item with the proper key, as the array can have thousands of items.
Thanks in advanced!
Despite your caveat, a loop is the obvious solution:
$newArray = [];
foreach($oldArray as $item)
$newArray[$item['id']] = $item;
If the problem you have is not specifically with a loop, but rather creating a copy of the array is causes excessive memory consumption, then you can edit the array in place, with a for loop:
for($i=0; $i<count($oldArray); $i++){
$oldArray[$oldArray[$i]['id']] = $oldArray[$i];
unset($oldArray[$i]);
}
Note this works because the id elements are alphanumeric strings, if they where simple integars then the above code could overwrite sections.
The only other solution is to build the correct array in the 1st place, in a similar manner.
For example, using PDO::fetch instead of PDO::fetchAll:
//$newArray = $sth->fetchAll(PDO::FETCH_ASSOC);
$newArray = [];
while($row = $sth->fetch(PDO::FETCH_ASSOC))
$newArray[$row['id']] = $row;
You can't overwrite keys while iterating through an array "on the fly". So here is solution with array_map which produces an array with needed structure:
// assuming $arr is your initial array
$result = [];
array_map(function($a) use (&$result){
$result[$a['id']] = $a;
}, $arr);
// $result contains the needed array
You can add needed key during creation of this array.

PDO fetchAll() primary key as array group key

I want to store the contents of a specific database into an array, grouped by their primary keys. (Instead of the useless way PDO fetchAll() organises them).
My current code:
$DownloadsPDO = $database->dbh->prepare("SELECT * FROM `downloads`");
$DownloadsArray = $DownloadsPDO->execute();
$DownloadsArray = $DownloadsPDO->fetchAll();
Which then outputs:
Array ( [0] => Array ( [id] => 0 [0] => 0 [path] => /xx-xx/testfile.zip [1] => /xx-xx/testfile.zip [name] => Test Script [2] => Test Script [status] => 1 [3] => 1 ) [1] => Array ( [id] => 1 [0] => 1 [path] => /xx-xx/test--file.zip [1] => /xxxx/testfile.zip [name] => New Script-UPDATE [2] => New Script-UPDATE [status] => 1 [3] => 1 ) )
I was considering to use PDO::FETCH_PAIR, however I will be very soon expanding the amount of data I want to be able to use on this script. This works currently, but when I start to expand the amount of downloads and more clients come into play, obviously the way the data is grouped causes an issue.
Is it possible for me to group each array by their primary key (which is id)?
You can just use
$results = array_map('reset', $stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC))
PDO::FETCH_GROUP|PDO::FETCH_ASSOC returns an array of arrays. The first column is used as the key, and then within key is an array of all the results for that key. However, in our scenario each key will only contain 1 row. reset() returns the first element in array, thus eliminating 1 level of nesting.
This should yield what you are looking for :
$results = $pdos->fetchAll(\PDO::FETCH_UNIQUE|\PDO::FETCH_ASSOC);
I decided to just loop through the results with fetch() and enter them into an array as I go along, this is the code I have used and it works just fine:
$DownloadsPDO = $database->dbh->query("SELECT * FROM `downloads`");
$Array = array();
while ($d = $DownloadsPDO->fetch()) {
$Array[$d['id']]["id"] = $d['id'];
$Array[$d['id']]["name"] = $d['name'];
$Array[$d['id']]["path"] = $d['path'];
}
// Outputs
Array ( [1] => Array ( [id] => 1 [name] => Test Script [path] => /xxxx/testfile.zip ) [2] => Array ( [id] => 2 [name] => New Script-UPDATE [path] => /xxxx/testfile.zip ) )
Which uses the primary key (being id) as the name for the array key, and then adds the data into it.
Thought I would add this as the answer as this solved it, thanks to the guys that helped out and I hope this is helpful to anyone else hoping to achieve the same thing.
I'd like to point out the only solution that works for me:
fetchAll(\PDO::FETCH_GROUP|\PDO::FETCH_UNIQUE|\PDO::FETCH_ASSOC);
Beware that this will strip the first column from the resultset. So the query must be:
SELECT id_keyname AS arrkey, id_keyname, .... FROM ...
I'm still suggesting you to loop using fetch() method. Otherwise, you can use array_reduce() to iterate over the array. A sample on codepad is here.
The code(in human readable form) will be:
$myFinalArray = array_reduce($myInputArray, function($returnArray, $temp) {
$temp2 = $temp['id'];
unset($temp['id']);
$returnArray[$temp2] = $temp;
return $returnArray;
}
);
So, my question is; is it possible for me to group each array by their
primary key (which is id)
Off course, you have 2 options here: Either to change the query or parse a result-set.
So, I'm sure you don't want to change query itself, so I'd go with parsing result-set.
Note:
You should use prepared SQL statements when they make sense. If you want to bind some parameters then its OKAY. But in this case, you only want get get result-set, so prepare() and fetch() will be kinda overdo.
So, you have:
Array ( [0] => Array ( [id] => 0 [0] => 0 [path] => /xx-xx/testfile.zip [1] => /xx-xx/testfile.zip [name] => Test Script [2] => Test Script [status] => 1 [3] => 1 ) [1] => Array ( [id] => 1 [0] => 1 [path] => /xx-xx/test--file.zip [1] => /xxxx/testfile.zip [name] => New Script-UPDATE [2] => New Script-UPDATE [status] => 1 [3] => 1 ) )
And you want:
Array( [id] => Array('bar' => 'foo') ....)
Well, you can do something like this:
$stmt = $database->dbh->query("SELECT * FROM `downloads`");
$result = array();
foreach($stmt as $array){
$result[$array['id']] = $array;
}
print_r($result); // Outputs: Array(Array('id' => Array(...)))

Change index order in array

Been kind of stuck on this one for a while now, so any help would be appreciated. I have one array (left) that contains a list of elements, the goal is to sort another arrays (right) keys with the values from the left array.
The left array
Array
(
[0] => ID
[1] => FirstName
[2] => LastName
[3] => Address
)
The right array
Array
(
[0] => Array
(
[FirstName] => Pim
[Address] => Finland
[LastName] => Svensson
[ID] => 3
)
[1] => Array
(
[FirstName] => Emil
[Address] => Sweden
[LastName] => Malm
[ID] => 5
)
)
What I'm trying to accomplish would be similar to this
Array
(
[0] => Array
(
[ID] => 3
[FirstName] => Pim
[LastName] => Svensson
[Address] => Finland
)
Anyone? :)
Oh, I'm running php 5.3, if it helps!
$output = array();
foreach ( $right as $array ) {
foreach ( $left as $field ) {
$temp[$field] = $array[$field];
}
$output[] = $temp;
}
You can use uksort() which lets you sort array keys by a user defined function. E.g.:
function sort_by_array($array) {
// create a sorting function based on the order of the elements in the array
$sorter = function($a, $b) use ($array) {
// if key is not found in array that specifies the order, it is always smaller
if(!isset($array[$a])) return -1;
if($array[$a] > $array[$b]) {
return 1;
}
return ($array[$a] == $array[$b]) ? 0 : -1;
};
return $sorter;
}
// $array contains the records to sort
// $sort_array is the array that specifies the order
foreach($array as &$record) {
uksort($record, sort_by_array(array_flip($sort_array)));
}
I make use of the possibility in 5.3 to define functions dynamically and I use array_flip() to transform:
Array
(
[0] => ID
[1] => FirstName
[2] => LastName
[3] => Address
)
to
Array
(
[ID] => 0
[FirstName] => 1
[LastName] => 2
[Address] => 3
)
This makes it easier to compare the keys later.
You must explode the array
Store the array in a variable like this
$array = Array
(
[0] => Array
(
[ID] => 3
[FirstName] => Pim
[LastName] => Svensson
[Address] => Finland
);
and then explode the array
after exploding the array you will get the parameters of the array seperated then you can use implode function the arrange them in anyorder as you wish
I'd take a step back and look at what you really need to do. The array is associative, so you can access the correct element instantly, right? So you don't really need it to be in order, unless you print output with foreach.
I'd suggest one of the following solutions:
If you need the "right" array to be in key-order, then look at the database query / similar and select the columns in the order you need them.
Foreach person you want to print, look up the order in the "left" array, then print the corresponding value of that key in the "right" array.
Well, your question it's uncommon, usually the associative arrays are used to resolve any problems about "position".
Anyway, there are many way to do what you are looking for what are you looking for.
You can use list() but it's position based:
foreach($oldArray as $o)
{
list($firstName,$lastName,$address,$id)=$oldArray;
$newArray[]=array($id,$firstName,$lastName,$address);
}
But the best way to solve your problem it's fill the array directly in the right order instead of re-sort after :)

Categories