php array_map removes more than required - php

I have an array like the following . . .
Array
(
[code] => BILL
[assets] => Array
(
[en] => Array
(
[labels] => Array
(
[datestamp] => April 30, 2013
)
[data] => Array
(
[Equity] => 88.83000000000
[Global] => 10.84000000000
[Other] => 0.33099095766
)
)
)
)
I have run the array_map function on this array to remove the [en] array
$en = array_map(function ($e){ return $e['en']; } , $en );
note how the resulting array has truncated the value for [code] from BILL to B
Array
(
[code] => B
[assets] => Array
(
[labels] => Array
(
[datestamp] => April 30, 2013
)
[data] => Array
(
[Equity] => 88.83000000000
[Global] => 10.84000000000
[Other] => 0.33099095766
)
)
)
Any tips on how to avoid that from happening. It is removing the array with the key [en] as required, but I don't want the value for [code] to be truncated.
Thanks.

You could perform type checking:
$en = array_map(function ($e){
if (is_array($e)) {
return $e['en'];
} else {
return $e;
}
} , $en );
Although it might suffice to do just this:
$en['assets'] = $en['assets']['en'];

Hello instead of passing entire array you mentioned as argument, you can pass the assets part of array as argument to array_map function :
$en_new = array_map(function ($e){ return $e['en']; } , $en['assets'] );
and then append the code part:
$en_new['code'] = $en['code'];

Related

add array value in php

Hello Iam new in Php I have Some Dout in Array
this is my array
Array
(
[files] => Array
(
[2] => abc.zip
[3] => xyz.rar
)
)
I need to add String in Array Values.. Like this
Array
(
[files] => Array
(
[2] => domain.com/abc.zip
[3] => domain.com/xyz.rar
)
)
I want Add Every Values domain.com/ How his Possible(sorry for bad English)
Just a simple loop and concat...
foreach($array['files'] as $key=>$value){
$array['files'][$key] = "domain.com/".$value;
}
You can do it using array_map:
<?php
$source = array(
'files' => array(
1 => 'abc.zip',
3 => 'xyz.rar'
)
);
$prefix = 'domain.com/';
$source['files'] = array_map(
function ($el) use ($prefix) {
return $prefix.$el;
},
$source['files']
);
print_r($source);
You can try this code here

Looping through and clearing arrays

I have arrays within arrays, all with varying amounts of information. My CSV table currently has the fields Name, Email, and Phone Number.
Below is my array;
Array
(
[0] => Array
(
[0] => Name
[1] => Email
[2] => Phone Number
)
[1] => Array
(
[0] => Mick
[1] => mick#mick.com
[2] => 01234 324234
)
[2] => Array
(
[0] => james
[1] => james#james.com
[2] =>
)
[3] => Array
(
[0] => reg
[1] => reg#reg.com
[2] => 10293 467289
)
)
I wish to loop through and remove these null values and combine the Email and Phone Number into Info end up with an array which resembles
Array
(
[0] => Array
(
[0] => Name
[1] => Info
)
[1] => Array
(
[0] => Mick
[1] => mick#mick.com + 01234 324234
)
[2] => Array
(
[0] => james
[1] => james#james.com
)
[3] => Array
(
[0] => reg
[1] => reg#reg.com + 10293 467289
)
)
Here is my current script, I am recienving the error;
<b>Warning</b>: array_filter() expects parameter 2 to be a valid callback, no array or string given in <b>C:\Users\Lydia\Documents\XAMPP\htdocs\CSV.php</b> on line <b>21</b><br />
every time that I loop through the changeRow() function, any help greatly appreciated
index.php
<?php
include 'CSV.php';
header('Content-type: text/plain');
$file = read_csv('Book1.csv');
$input = changeRow($file);
CSV.php
....
....
function changeRow($rows){
$len = count($rows);
for($i = 0; $i < $len; $i++){
$rows = array_filter($rows[0],0);
}
}
Can use array_map() instead of foreach(). Example:
$file = read_csv('Book1.csv');
$input = array_map(function($v){
$phone = (isset($v[2]) && $v[2]) ? ' + '. $v[2] : '';
return array($v[0], $phone);
},$file );
if(isset($result[0][1])) $result[0][1] = 'Info';
print '<pre>';
print_r($input);
print '</pre>';
I'll provide two methods that output the requested array structure. (PHP Demo Link) These methods iterate the array, check if the iteration is dealing with the "column heading" subarray or not, then conditionally appending the value from subarray element [2] to subarray element [1] using + as glue.
Method #1: foreach()
foreach($array as $index=>$item){
if(!$index){
$result[]=['Name','Info'];
}else{
$result[]=[$item[0],$item[1].(strlen($item[2])?" + $item[2]":'')];
}
}
var_export($result);
Method #2 array_map()
var_export(
array_map(function($index,$item){
if(!$index){
return ['Name','Info'];
}else{
return [$item[0],$item[1].(strlen($item[2])?" + $item[2]":'')];
}
},array_keys($array),$array)
);
Output: (from either method)
array (
0 =>
array (
0 => 'Name',
1 => 'Info',
),
1 =>
array (
0 => 'Mick',
1 => 'mick#mick.com + 01234 324234',
),
2 =>
array (
0 => 'james',
1 => 'james#james.com',
),
3 =>
array (
0 => 'reg',
1 => 'reg#reg.com + 10293 467289',
),
)
ps. If you want to remove the $index==0 check that is iterated each time, you can manually overwrite the first subarray after the loop is finished like this: (PHP Demo Link) *this just means you will be "writing" data to the first subarray twice.
foreach($array as $item){
$result[]=[$item[0],$item[1].(strlen($item[2])?" + $item[2]":'')];
}
$result[0]=['Name','Info'];
var_export($result);
or
$result=array_map(function($item){return [$item[0],$item[1].(strlen($item[2])?" + $item[2]":'')];},$array);
$result[0]=['Name','Info'];
var_export($result);
pps. "Passing by Reference" can be used for this task, but I've elected not to use &$array because it can risk causing trouble "downscript" and many developers advise against using it until other methods are inadequate. Here is what that can look like: (PHP Demo Link)
foreach($array as &$item){
if(strlen($item[2])) $item[1].=" + $item[2]";
unset($item[2]);
}
$array[0]=['Name','Info'];
var_export($array);
unset($item); // var_export($item); // ($item = NULL)

grabbing only certain array inside array

Basically, I'm receiving an array() from the Yahoo Messenger API in PHP and am in the process of developing an notification system, It returns an array with both the IM received from an chat and my contacts.
Array (
[0] => Array
(
[message] => Array
(
[status] => 1
[sequence] => 0
[sender] => SenderCurtis
[receiver] => receiverCurtis
[msg] => #1
[timeStamp] => 1374187598
[hash] => y2qlDf8uTq8tXzgzrsSMyjQB+W2uDg==
[msgContext] => y2qlDf8uTq8tXzgzrsSMyjQB+W2uDg==
)
)
[1] => Array
(
[buddyInfo] => Array
(
[sequence] => 1
[contact] => Array
(
[0] => Array
(
[sender] => SenderCurtis
[presenceState] => 0
[avatarUser] => 0
[avatarPreference] => 0
[clientCapabilities] => 8915971
[clientUserGUID] => MI7STHUYOAMCGE5TNTY7CJPFWM
)
)
)
)
[2] => Array
(
[message] => Array
(
[status] => 1
[sequence] => 2
[sender] => SenderCurtis
[receiver] => receiverCurtis
[msg] => #2
[timeStamp] => 1374187601
[hash] => 3+2s9sIvjPRdvneQsMgVNCKBTFgKwQ==
[msgContext] => 3+2s9sIvjPRdvneQsMgVNCKBTFgKwQ==
)
)
[3] => Array
(
[buddyInfo] => Array
(
[sequence] => 3
[contact] => Array
(
[0] => Array
(
[sender] => myContactUser1#yahoo.com
[presenceState] => 0
[avatarUser] => 0
[avatarPreference] => 0
[clientCapabilities] => 8915971
[clientUserGUID] => UQU3WV7ZOZ2OTGLJQUE2QJU4ZU
)
)
)
)
)
How can I grab just the message array() and iterate through it? such as "Message 1", "Message2" etc...
If you're trying to filter the array values for the key 'message', you could do something like this in PHP:
$messages = array();
foreach ($response as $key => $data) {
if (array_key_exists('message', $data)) {
$msgArray = $data['message'];
$messages[] = $msgArray;
}
}
In the above sample, I'm storing the messages in their own array. But you could process the data right inside the for-loop too, if you want that.
I think that array_map() is the function you are looking for here. The array_map function allows you to execute a callback on each element of an existing array and assemble a new array consisting only of the values returned by the callback.
What you would want to do is something like this :
$data = // lets assume this is the data you received
$messages_data = array_map( "extract_message", $data );
function extract_message( $data_item ){
if ( array_key_exists( 'message', $data_item ) ){
return $data_item[ 'message' ];
}
}
Now your $message_data array will contain only the message arrays from the original array.
foreach ($var[0] as $key => $value)
{
do things with each message
}
where $var is substituted for your actual variable name
Just filter your array using array_filter.
$messages = array_filter($data, function($a){ return isset($a["message"]); });
Then use array_map to get rid of the unwanted intermediate array.
$messages = array_map(function($a){ return $a["message"]; }, $message);
then you can iterate over it with a foreach or whatever.
Because I like SPL iterators here another solution. Works with PHP >= 5.1.0.
class MessageIterator extends FilterIterator
{
public function accept()
{
return array_key_exists('message', $this->getInnerIterator()->current());
}
public function current()
{
$current = parent::current();
return $current['message'];
}
}
$iterator = new MessageIterator(new ArrayIterator($array));
foreach ($iterator as $message) {
print_r($message);
}

populate php multidimenssional array with foreach loop

I need to create an array like the following:
$va_body=array(
"bundles" => array(
"$table.$elem" => array("convertCodesToDisplayText" => true),
"$table.$elem" => array("convertCodesToDisplayText" => true),
)
);
$table is a string that does not change and $elem is extracted from an array.
I got close with the following code, but it ends up with only the last value from $bund, $bund is an array with two values. I guess the array is redeclared in each loop?
$va_body=array(); // declare the array outside the loop
foreach ($bund as $elem ) {
$va_body['bundles'] = array($table.".".$elem=>array("convertCodesToDisplayText" => true));
}
$bund array has two elements "description" and "type_id".
$va_body['bundles'][] // Adding [] doesn't work as it modifies the expected outcome.
print_r($va_body) looks like this:
Array (
[bundles] => Array (
[ca_objects.type_id] => Array (
[convertCodesToDisplayText] => 1
)
)
)
I need it to be:
Array (
[bundles] => Array (
[ca_objects.description] => Array (
[convertCodesToDisplayText] => 1
)
[ca_objects.type_id] => Array (
[convertCodesToDisplayText] => 1
)
)
)
Thanks in advance.
#phpisuber01
Using:
$va_body['bundles'][] = array($table.".".$elem=>array("convertCodesToDisplayText" => true));
print_r($va_body); looks like this:
Array (
[bundles] => Array (
[0] => Array (
[ca_objects.description] => Array (
[convertCodesToDisplayText] => 1
)
)
[1] => Array (
[ca_objects.type_id] => Array (
[convertCodesToDisplayText] => 1
)
)
)
)
And I need it to be like this:
Array (
[bundles] => Array (
[ca_objects.description] => Array (
[convertCodesToDisplayText] => 1
)
[ca_objects.type_id] => Array (
[convertCodesToDisplayText] => 1
)
)
)
Answer by #phpisuber01:
$va_body['bundles'][$table.".".$elem] = array("convertCodesToDisplayText" => true);
Thank you very much!
You need to make an array of arrays. In your loop change the following line:
$va_body['bundles'][$table.".".$elem] = array("convertCodesToDisplayText" => true);
Added [] after $va_body['bundles'].
All this does is keep adding the new bundles into the array. Your original code is overwriting bundles each iteration. That's why you only get the last one.
Updated to get closer to OP's exact needs.
$va_body = array();
$va_body['bundles'] = array();
foreach ($bund AS $elem)
{
$va_body['bundles']["{$table}.{$elem}"] = array("convertCodesToDisplayText" => true);
}

How can I create multidimensional arrays from a string in PHP?

So My problem is:
I want to create nested array from string as reference.
My String is "res[0]['links'][0]"
So I want to create array $res['0']['links']['0']
I tried:
$result = "res[0]['links'][0]";
$$result = array("id"=>'1',"class"=>'3');
$result = "res[0]['links'][1]";
$$result = array("id"=>'3',"class"=>'9');
when print_r($res)
I see:
<b>Notice</b>: Undefined variable: res in <b>/home/fanbase/domains/fanbase.sportbase.pl/public_html/index.php</b> on line <b>45</b>
I need to see:
Array
(
[0] => Array
(
[links] => Array
(
[0] => Array
(
[id] => 1
[class] => 3
)
)
)
[1] => Array
(
[links] => Array
(
[0] => Array
(
[id] => 3
[class] => 9
)
)
)
)
Thanks for any help.
So you have a description of an array structure, and something to fill it with. That's doable with something like:
function array_create(&$target, $desc, $fill) {
preg_match_all("/[^\[\]']+/", $desc, $uu);
// unoptimized, always uses strings
foreach ($uu[0] as $sub) {
if (! isset($target[$sub])) {
$target[$sub] = array();
}
$target = & $target[$sub];
}
$target = $fill;
}
array_create( $res, "[0]['links'][0]", array("id"=>'1',"class"=>'3') );
array_create( $res, "[0]['links'][1]", array("id"=>'3',"class"=>'9') );
Note how the array name itself is not part of the structure descriptor. But you could theoretically keep it. Instead call the array_create() function with a $tmp variable, and afterwards extract() it to achieve the desired effect:
array_create($tmp, "res[0][links][0]", array(1,2,3,4,5));
extract($tmp);
Another lazy solution would be to use str_parse after a loop combining the array description with the data array as URL-encoded string.
I have a very stupid way for this, you can try this :-)
Suppose your string is "res[0]['links'][0]" first append $ in this and then put in eval command and it will really rock you. Follow the following example
$tmp = '$'.'res[0]['links'][0]'.'= array()';
eval($tmp);
Now you can use your array $res
100% work around and :-)
`
$res = array();
$res[0]['links'][0] = array("id"=>'1',"class"=>'3');
$res[0]['links'][0] = array("id"=>'3',"class"=>'9');
print_r($res);
but read the comments first and learn about arrays first.
In addition to mario's answer, I used another function from php.net comments, together, to make input array (output from jquery form serializeArray) like this:
[2] => Array
(
[name] => apple[color]
[value] => red
)
[3] => Array
(
[name] => appleSeeds[27][genome]
[value] => 201
)
[4] => Array
(
[name] => appleSeeds[27][age]
[value] => 2 weeks
)
[5] => Array
(
[name] => apple[age]
[value] => 3 weeks
)
[6] => Array
(
[name] => appleSeeds[29][genome]
[value] => 103
)
[7] => Array
(
[name] => appleSeeds[29][age]
[value] => 2.2 weeks
)
into
Array
(
[apple] => Array
(
[color] => red
[age] => 3 weeks
)
[appleSeeds] => Array
(
[27] => Array
(
[genome] => 201
[age] => 2 weeks
)
[29] => Array
(
[genome] => 103
[age] => 2.2 weeks
)
)
)
This allowed to maintain numeric keys, without incremental appending of array_merge. So, I used sequence like this:
function MergeArrays($Arr1, $Arr2) {
foreach($Arr2 as $key => $Value) {
if(array_key_exists($key, $Arr1) && is_array($Value)) {
$Arr1[$key] = MergeArrays($Arr1[$key], $Arr2[$key]);
}
else { $Arr1[$key] = $Value; }
}
return $Arr1;
}
function array_create(&$target, $desc, $fill) {
preg_match_all("/[^\[\]']+/", $desc, $uu);
foreach ($uu[0] as $sub) {
if (! isset($target[$sub])) {
$target[$sub] = array();
}
$target = & $target[$sub];
}
$target = $fill;
}
$input = $_POST['formData'];
$result = array();
foreach ($input as $k => $v) {
$sub = array();
array_create($sub, $v['name'], $v['value']);
$result = MergeArrays($result, $sub);
}

Categories