I've this piece of code in which I want to know is there anyway I could avoid pass by reference
public function formatNumbers($numbersData){
$result = array();
array_map(
function($row) use (&$result) {
$result[$row['GroupId']][$row['Type']] = $row['value'];
}, $numbersData
);
return $result;
}
Input: $numbersData =
Array
(
[0] => Array
(
[GroupId] => 2
[Type] => 1
[value] => 82000
)
[1] => Array
(
[GroupId] => 2
[Type] => 3
[value] => 52000
)
[2] => Array
(
[GroupId] => 2
[Type] => 4
[value] => 30105
)
[3] => Array
(
[GroupId] => 2
[Type] => 7
[value] => 13266
)
)
Output is
Array
(
[2] => Array
(
[1] => 82000
[3] => 52000
[4] => 30105
[7] => 13266
)
)
I know I can do it using foreach, but I want to know that if there anyway to use array map for this without pass by reference.Any help would be greatly appreciated.
Wrong kind of operation. You're not looking for a mapping of values, you're looking for an array reduction:
return array_reduce($numbersData, function(array $acc, array $row) {
$acc[$row['GroupId']][$row['Type']] = $row['value'];
return $acc;
}, []);
You can do it using array_column() function.
$arr = array(array('GroupId'=>2,'Type' => 1,'value' => 82000),array('GroupId'=>2,'Type' => 3,'value' => 52000),array('GroupId'=>2,'Type' => 4,'value' => 30105),array('GroupId'=>2,'Type' => 7,'value' => 13266));
print_r(array_column($arr, 'value', 'Type'));
Related
So i have this array that i get from query. The array look like this when i print_r
Array
(
[0] => Array
(
[Name] => NAME 1
[Last] => LastValue1
[Bid] =>
[Ask] =>
)
[1] => Array
(
[Name] => NAME 1
[Last] =>
[Bid] => BidValue1
[Ask] =>
)
[2] => Array
(
[Name] => Name 2
[Last] => LastValue2
[Bid] => BidValue2
[Ask] =>
)
[3] => Array
(
[Name] => NAME 1
[Last] =>
[Bid] =>
[Ask] => AskValue1
)
[4] => Array
(
[Name] =>Name 2
[Last] =>
[Bid] =>
[Ask] => AskValue2
)
)
and i want to achieve array looks like this
Array
(
[0] => Array
(
[Name] => NAME 1
[Last] => LastValue1
[Bid] => BidValue1
[Ask] => AskValue1
)
[2] => Array
(
[Name] => Name 2
[Last] => LastValue2
[Bid] => BidValue2
[Ask] => AskValue2
)
)
I try this way (get it from google)
$result = array();
foreach ($newArray as $element) {
$result[$element['Name']][] = $element;
}
echo "<pre>";print_r($result);
But it is not showing the result that i want. How can i achieve it ?
thanks in advance and sorry for my english
You can use below snippet for the same,
$result = [];
foreach ($newArray as $element) {
foreach ($element as $key => $value) {
// checking if value for key is already added to result array
if ((!empty($result[$element['Name']]) && !array_key_exists($key, $result[$element['Name']])) || empty($result[$element['Name']])) {
if (!empty($value)) { // checking if value not empty
$result[$element['Name']] = ($result[$element['Name']] ?? []);
// merge it to group wise name result array
$result[$element['Name']] = array_merge($result[$element['Name']], [$key => $value]);
}
}
}
}
array_merge — Merge one or more arrays
array_key_exists — Checks if the given key or index exists in the array
Demo
Output:-
Array
(
[0] => Array
(
[Name] => NAME1
[Last] => LastValue1
[Bid] => BidValue1
[Ask] => AskValue1
)
[1] => Array
(
[Name] => Name2
[Last] => LastValue2
[Bid] => BidValue2
[Ask] => AskValue2
)
)
Here is the shortest and simple solution by using foreach with array_filter
foreach($a as &$v){
$v = array_filter($v);
isset($r[$v['Name']]) ? ($r[$v['Name']] += $v) : ($r[$v['Name']] = $v);
}
You can use array_values to re arrange the order of array.
Working example : https://3v4l.org/XeQHa
I'm trying to unset two specific array positions which contain two values.
My actual code to fill the array.
function get_store_list(){
$data = #file_get_contents('http://www.zwinky.com/xml/clothingList.xml');
$data = #simplexml_load_string($data);
$data = $data->xpath('//stores/store');
foreach($data as $store) {
$storeArray[] = array(
"name" => (string)$store['name'],
"id" => (string)$store['id']
);
}
return $storeArray;
}
$store = get_store_list();
The array looks like the following incase ill echo it out using print_r function:
Array
(
[0] => Array
(
[name] => Artizans
[id] => 20037336
)
[1] => Array
(
[name] => Bwabies!
[id] => 20080134
)
[2] => Array
(
[name] => Crave Mart
[id] => 20097365
)
[3] => Array
(
[name] => David & Goliath
[id] => 20099998
)
[4] => Array
(
[name] => Domo
[id] => 20098166
)
[5] => Array
(
[name] => Emily the Strange
[id] => 20101926
)
[6] => Array
(
[name] => Garfield
[id] => 20098167
)
[7] => Array
(
[name] => Jetsetter
[id] => 26
)
[8] => Array
(
[name] => Like Dat
[id] => 3
)
[9] => Array
(
[name] => Paris Hilton
[id] => 21
)
[10] => Array
(
[name] => Peppermint Place
[id] => 12
)
[11] => Array
(
[name] => Rocawear
[id] => 19
)
[12] => Array
(
[name] => ShoeBuy
[id] => 10
)
[13] => Array
(
[name] => Skelanimals
[id] => 20100198
)
[14] => Array
(
[name] => Snoop Dogg
[id] => 20
)
[15] => Array
(
[name] => SW&TH
[id] => 20096121
)
[16] => Array
(
[name] => The Castle
[id] => 1
)
[17] => Array
(
[name] => The Lair
[id] => 4
)
[18] => Array
(
[name] => The Mix
[id] => 923
)
[19] => Array
(
[name] => The Powerpuff Girls
[id] => 20098121
)
[20] => Array
(
[name] => The Surf Shop
[id] => 5
)
[21] => Array
(
[name] => Tie The Knot
[id] => 20076231
)
[22] => Array
(
[name] => tokidoki
[id] => 20099224
)
[23] => Array
(
[name] => University Club
[id] => 2
)
[24] => Array
(
[name] => Z Avenue
[id] => 6
)
[25] => Array
(
[name] => Z's Greetings
[id] => 20099506
)
)
Now $store does contain 2 array indexes which I have to delete. Which are the following ids: 21 and 20076231
I've been trying the following already:
Array search code without beeing success. Does anyone have a idea what I could try?
There are a handful different approaches for this simple issue. One of them could be using function array_filter():
/**
* #param array $list the list to process
* #param array $IDsToRemove the IDs of elements to remove from $list
* #return array a subset of $list that does not contain elements having 'id' in $IDsToRemove
*/
function removeFromArray(array $list, array $IDsToRemove)
{
return array_filter(
// Filter the input list...
$list,
// ... using a function...
function (array $item) use ($IDsToRemove) {
// ... that accepts an element if its "id" is not in $IDsToRemove
return ! in_array($item['id'], $IDsToRemove);
}
);
}
// Usage
$filteredStore = removeFromArray($store, array(21, 20076231));
Try this in your loop, this will not include in your array than no need to unset like this:
foreach($data as $store) {
if($store['id'] == '20076231')
continue;
$storeArray[] = array(
"name" => (string)$store['name'],
"id" => (string)$store['id']
);
}
If you need to unset an item from your array after it's been created, take a look at array_map.
First map your array to retrieve the index of each ID.
$map = array_map(function($item){ return $item['id']; }, $store);
Then get the index of your ID from the map (e.g. 21).
$index = array_search(21, $map);
Then remove with array_splice.
array_splice($store, $index, 1);
why not use directly the id in your $storeArray? And as it seems to be integer why do you force it to (string)?
Try this:
function get_store_list(){
$data = #file_get_contents('http://www.zwinky.com/xml/clothingList.xml');
$data = #simplexml_load_string($data);
$data = $data->xpath('//stores/store');
foreach($data as $store) {
$storeArray[(int)$store['id']] = array(
"name" => (string)$store['name']
);
}
return $storeArray;
}
// delete the keys you want
unset ($storeArray[21], $storeArray[20076231]);
// or if you have more ids to delete you can create a deleteArray
$deleteArray = array(2, 20076231);
foreach ($deleteArray as $toDelete){
unset($storeArray($toDelete);
}
One line code is cool but sometimes explicit code is preferable.
function filter_by_id(array $data, $id)
{
foreach ($data as $k => &$v) {
foreach ((array) $id as $i) {
if ($v['id'] === $i) {
$v = null;
}
}
}
// 'array_filter()' produces a new array without the null entries.
// 'array_values()' produces a new array with indexes without gaps.
return array_values(array_filter($data));
}
You can filter by one id at time
$store = filter_by_id($store, 21);
Or you can filter multiple ids at the same time:
$store = filter_by_id($store, [21, 20076231]);
this is my array
Array
(
[0] => Array
(
[id] => 277558
[text_value] => Jif
[response_count] => 13
[response_percentage] => 92
)
[1] => Array
(
[id] => 277559
[text_value] => Peter Pan
[response_count] => 20
[response_percentage] => 6
)
)
after completing the operation the out put should be
Array
(
[0] => Array
(
[id] => 277558
[text_value] => Jif
[response_count] => 13
[response_percentage] => 92
[encode_param]=>ds!##^(*!ggsfh8236542jsdgf82*&61327
)
[1] => Array
(
[id] => 277559
[text_value] => Peter Pan
[response_count] => 20
[response_percentage] => 6
[encode_param]=>ds!##^(*!ggsfh8236542jsdgf82*&61327
)
)
you can see a new array value encode_paramis added
in that function do some encode algorithms
i have achieve this in the foreach looping statement
but i need to do it in array maping
Can anybody help thank u in advance
$encode_func = function($elem) { // declare function to encode
return $elem['text_value'];
}
$result = array_map(function($elem) use($encode_func) {
$elem['encode_param'] = $encode_func($elem);
return $elem;
}, $array);
Hope it helps.
This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 8 years ago.
I've trawled a lot of questions and php manual, but I can't find a way to get sort this data in a graceful way. There may not be, but I'll settle for non-graceful.
At the moment I have a page that builds 4 arrays with data from post. The number of keys changes depending on the input;
// Grab the Tasks
$arraytask = $_POST["task"];
// Grab the Relusers
$arrayreluser = $_POST["reluser"];
// Grab the Usernames
$arrayuser = $_POST["user"];
// Grab the License Types
$arraylicense = $_POST["license"];
$result = array();
foreach( $arraytask as $key => $val) {
$result[] = array('key'=>$key, 'value'=>$val);
}
foreach( $arrayreluser as $key => $val) {
$result[] = array('key'=>$key, 'value'=>$val);
}
foreach( $arrayuser as $key => $val) {
$result[] = array('key'=>$key, 'value'=>$val);
}
foreach( $arraylicense as $key => $val) {
$result[] = array('key'=>$key, 'value'=>$val);
}
ksort($result); // I know this does nothing, I was hoping it would recursively sort or something
At the moment, the output on an example submission looks like (and sorry for the long formatting):
print_r($result);
Array (
[0] => Array (
[key] => 0
[value] => 123 )
[1] => Array (
[key] => 1
[value] => 456 )
[2] => Array (
[key] => 2
[value] => 789 )
[3] => Array (
[key] => 0
[value] => qwe )
[4] => Array (
[key] => 1
[value] => rty )
[5] => Array (
[key] => 2
[value] => uio )
[6] => Array (
[key] => 0
[value] => asd )
[7] => Array (
[key] => 1
[value] => fgh )
[8] => Array (
[key] => 2
[value] => jkl )
[9] => Array (
[key] => 0
[value] => license 1 )
[10] => Array (
[key] => 1
[value] => license 2 )
[11] => Array (
[key] => 2
[value] => license 3 )
)
However I want the output to be like
print_r($result);
Array (
[0] => Array (
[key] => 0
[value] => 123 )
[3] => Array (
[key] => 0
[value] => qwe )
[6] => Array (
[key] => 0
[value] => asd )
[9] => Array (
[key] => 0
[value] => license 1 )
[1] => Array (
[key] => 1
[value] => 456 )
[4] => Array (
[key] => 1
[value] => rty )
[7] => Array (
[key] => 1
[value] => fgh )
[10] => Array (
[key] => 1
[value] => license 2 )
[2] => Array (
[key] => 2
[value] => 789 )
[5] => Array (
[key] => 2
[value] => uio )
[8] => Array (
[key] => 2
[value] => jkl )
[11] => Array (
[key] => 2
[value] => license 3 )
)
I know I'm sorting Arrays by their keys... I just can't think of a better way to sort this data.
At the moment I've looked at array_merge() which seems to overwrite duplicate keys, and I've tried a few variations of foreach loops which have just ended in tears for everyone involved.
An alternative way to ask this question would be "If I can't sort these arrays by the keys within them, can I merge my 4 arrays so that the values of each array compile in to a single array, based off key?"
An acceptable (seemingly more graceful) output would also be
Array (
[0] => Array (
[key] => 0
[value] => 123, qwe, asd, license 1 )
[1] => Array (
[key] => 1
[value] => 456, rty, fgh, license 2 )
[2] => Array (
[key] => 2
[value] => 789, uio, jkl, license 3 )
)
I'm just not sure I can append values to keys in an array, if I do not explicitly know how many keys there are.
Postscript: if there are typos here, that's because this is the example cut down from the actual code for clarity, and I'm sorry. My issue isn't typos.
::SOLUTION::
Thanks to vstm, this worked for combining multiple arrays into a more useful array data;
$result = array();
foreach($arraytask as $key => $val) {
$result[] = array(
'key' => $key,
'task' => $arraytask[$key],
'reluser' => $arrayreluser[$key],
'user' => $arrayuser[$key],
'license' => $arraylicense[$key],
'value' => implode(', ', array(
$arraytask[$key],
$arrayreluser[$key],
$arrayuser[$key],
$arraylicense[$key],
))
);
}
Shows the output as
Array (
[0] => Array (
[key] => 0
[task] => 123
[reluser] => qwe
[user] => asd
[license] => license 1
[value] => 123, qwe, asd, license 1 )
[1] => Array (
[key] => 1
[task] => 456
[reluser] => rty
[user] => fgh
[license] => license 2
[value] => 456, rty, fgh, license 2 ) )
Well it seems that your input data is already given in a way that would make sorting useless. Try it this way:
// Grab the Tasks
$arraytask = $_POST["task"];
// Grab the Relusers
$arrayreluser = $_POST["reluser"];
// Grab the Usernames
$arrayuser = $_POST["user"];
// Grab the License Types
$arraylicense = $_POST["license"];
$result = array();
foreach($arraytask as $key => $val) {
$result[] = array(
'key' => $key,
'task' => $arraytask[$key],
'reluser' => $arrayreluser[$key],
'user' => $arrayuser[$key],
'license' => $arraylicense[$key],
'value' => implode(', ', array(
$arraytask[$key],
$arrayreluser[$key],
$arrayuser[$key],
$arraylicense[$key],
))
);
}
Now you have your "seemingly graceful" output, plus access to all the fields which you might need for working with your data. No need for sorting.
Try by usort(). Example here...
function sortByValue($a, $b) {
return $a['key'] - $b['key'];
}
usort($arr, 'sortByValue');
print '<pre>';
print_r($arr);
and i got a problem (its big for me) :(
ok, i have some array like ...
Array(
[0] => Array
(
[id] => 1
[order_sn] => EU/2011/04/PO/5
[total] => 65
)
[1] => Array
(
[id] => 1
[order_sn] => EU/2011/04/RS/4
[total] => 230
)
[2] => Array
(
[id] => 1
[order_sn] => EU/2011/04/RS/3
[total] => 130
)
[3] => Array
(
[id] => 2
[order_sn] => EU/2011/04/RS/2
[total] => 100
)
[4] => Array
(
[id] => 2
[order_sn] => EU/2011/04/RS/1
[total] => 60
)
)
how to merge them if the array have same key value ... ?
the result that i need got is like this ...
Array(
[0] => Array
(
[id] => 1
[detail] => Array
(
[0] => Array
(
[order_sn] => EU/2011/04/PO/5
[total] => 65
)
[1] => Array
(
[order_sn] => EU/2011/04/RS/4
[total] => 230
)
[2] => Array
(
[order_sn] => EU/2011/04/RS/3
[total] => 130
)
)
)
[2] => Array
(
[id] => 2
[detail] => Array
(
[0] => Array
(
[order_sn] => EU/2011/04/RS/2
[total] => 100
)
[1] => Array
(
[order_sn] => EU/2011/04/RS/1
[total] => 60
)
)
)
)
im very need some help here, and im working on PHP ... what method should i do for this case?
i try too searching on google and in here ... but i dont know the keyword >.<
Many thanks before :)
regard, Stecy
Try like this:
<?php
$result = array();
foreach ($my_array as $v) {
$id = $v['id'];
$result[$id]['id'] = $id;
$result[$id]['detail'][] = array(
'order_sn' => $v['order_sn'],
'total' => $v['total'],
);
}
You can just loop over the array and build a resulting one:
// $a is your array
$r=array();
foreach($a as $v)
$r[$v['id']][]=array('order_sn'=>$v['order_sn'], 'total'=>$v['total']);
echo'<pre>';
var_dump($r);
Since you do the paring by ID, it is wise to have it as the key and all the data associated with it as the value. There's no need to also have id and detail.
foreach($origianlArray as $key => $value){
$newArray[$value['id']]['id'] = $value['id'];
$newArray[$value['id']]['detail'][] = array('order_sn' => $value['order_sn'], 'total' => $value['total']);
}
Check out the PHP array_merge function.