I have this code:
$ItemID = 'a62442e2-ca1f-4fd1-b80d-0d0dc511758e';
$GET_FreeTextFields = new \Picqer\Financials\Exact\ItemExtraField($connection);
$FreeTextFields = $GET_FreeTextFields->filter("ItemID eq guid'$ItemID'", '', '' );
$FreeTextFields01 = array();
$FreeTextFields02 = array();
foreach($FreeTextFields as $GET_FreeTextFields){
$FreeTextFields01[] = $GET_FreeTextFields->Value;
$FreeTextFields02[] = $GET_FreeTextFields->Number;
}
print_r($FreeTextFields01);
print_r($FreeTextFields02);
This outputs:
Value Array
(
[0] => 390
[1] => 804715
[2] => WW001
[3] => WHT/WHT/WHT
[4] => 39/42
[5] => 804715 WW00139/42
[6] => 3pk Quarter Socks
)
Numbers Array
(
[0] => 3
[1] => 4
[2] => 5
[3] => 6
[4] => 7
[5] => 8
[6] => 10
)
What this needs to output:
What i want if i use the first output so with 6 values in the array:
$FreeTextField01 = null
$FreeTextField02 = null
$FreeTextField03 = 390
$FreeTextField04 = 804715
$FreeTextField05 = WW001
$FreeTextField06 = WHT/WHT/WHT
$FreeTextField07 = 39/42
$FreeTextField08 = 804715 WW00139/42
$FreeTextField09 = null
$FreeTextField10 = 3pk Quarter Socks
But with other $ItemID, it can also output:
Value Array
(
[0] => 10100153
[1] => 2007
[2] => 350
[3] => 804082
[4] => WW006
[5] => WHT/NNY/OXGM
[6] => 35/38
[7] => 804082 WW00635/38
[8] => 0,00138857
[9] => Champion 3pk Quarter Socks
)
Numbers Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
[6] => 7
[7] => 8
[8] => 9
[9] => 10
)
What i want is that if a variable is not in the numbers list so 1-10, setting it to empty, and if the numbers is in the numbers array setting that number to the corresponding value variable. For example the number at [0] is 1 then set the variable $FreeTextField1 to $NumbersArray[0]->Value.
I keep making all kinds off loops but i just get stuck at the fact that the array length changes so that [6] can be the number 10 at one $itemID, but at another $ItemID, the number can be 6.
I tried researching this but I don't even know what I have to type in google to find this problem, that's why I'm describing it here.
edit i tried describing it a second time:
Yeah I'm having problems describing what i want, so let me try again. I get two arrays as output one with numbers that correspond with place it stands, as example you have FreeTextField0 thru FreeTextField10. What i tried to do is if (Numbers[0] == 0){ $FreeTextField0 = Value[0]}, but then I get the problem that Numbers[0] can be 3 or something else because if FreeTextField1 is empty i don't get a null value but nothing.
What i want if i use the first output so with 6 values in the array:
$FreeTextField01 = null
$FreeTextField02 = null
$FreeTextField03 = 390
$FreeTextField04 = 804715
$FreeTextField05 = WW001
$FreeTextField06 = WHT/WHT/WHT
$FreeTextField07 = 39/42
$FreeTextField08 = 804715 WW00139/42
$FreeTextField09 = null
$FreeTextField10 = 3pk Quarter Socks
I think this is what you're after but I have to say that I think you're barking up the wrong tree here. You really should not dynamically create variables in your script. To me, it is a serious code-smell and I think you should evaluate your design here.
http://sandbox.onlinephpfunctions.com/code/b245a0218ce174e68508139872f394def5409b05
<?php
// Test case
$values = [
'390',
'804715',
'WW001',
'WHT/WHT/WHT',
'39/42',
'804715 WW00139/42',
'3pk Quarter Socks'
];
$numbers = [3, 4, 5, 6, 7, 8, 10];
// Flip the $numbers array and then use the keys to find the corresponding values in the $values array
$intersection = array_unique(array_intersect_key($values, array_flip($numbers)));
// Fill in the missing keys and use `null` as the value
$output = $intersection + array_fill_keys(range(1,10), null);
// Sort the final output by the keys
ksort($output);
// Format the keys to match FreeTextField{00}
$output = array_combine(
array_map(function($k){ return 'FreeTextField'.str_pad($k, 2, '0', STR_PAD_LEFT); }, array_keys($output)),
$output
);
// Use the extract function to bring all those array keys + values into the symbol table.
// You can now use $FreeTextField01 - $FreeTextField10
extract($output);
var_dump($output);
UPDATE
http://sandbox.onlinephpfunctions.com/code/244c4f1ed45db398c48b8330c402b375eb358446
<?php
// Test case
$input = [
['Value' => '390', 'Number' => 3],
['Value' => '804715', 'Number' => 4],
['Value' => 'WW001', 'Number' => 5],
['Value' => 'WHT/WHT/WHT', 'Number' => 6],
['Value' => '39/42', 'Number' => 7],
['Value' => '804715 WW00139/42', 'Number' => 8],
['Value' => '3pk Quarter Socks', 'Number' => 10],
];
$intersection = [];
foreach ($input as $config) {
$value = $config['Value'];
$number = $config['Number'];
$intersection[$number] = $value;
}
// Fill in the missing keys and use `null` as the value
$output = $intersection + array_fill_keys(range(1,10), null);
// Sort the final output by the keys
ksort($output);
// Format the keys to match FreeTextField{00}
$output = array_combine(
array_map(function($k){ return 'FreeTextField'.str_pad($k, 2, '0', STR_PAD_LEFT); }, array_keys($output)),
$output
);
// Use the extract function to bring all those array keys + values into the symbol table.
// You can now use $FreeTextField01 - $FreeTextField10
extract($output);
var_dump($output);
Use ${$var}
If you want to see a doc about this type of var you can see it here:
http://php.net/manual/en/language.variables.variable.php
Related
I want to sort an existing array into 4 dimension array:
the "list" array that I have:
1 => "text1"
10 => "text10"
11 => "text11"
101 => "text101"
1011 => "text1011"
10123 => "text10123"
2 => "text2"
20 => "text20"
201 => "text201"
2011 => "text2011"
20111 => "text20111"
the array I want is one that has all the data sorted by each number (in 4 dimention) i mean that i won't have an other array in the end of $chapter[1] containing 10123 => "text10123" (this one will be in the same array as this one : 1011 => "text1011"
here is an exemple of the array i want
$chapter[1] = array(
1 => "text1", array(
10 => "text10", 11 => "text11", array(
101 => "text101", array(
1011 => "text1011", 10123 => "text10123" )
)
)
);
I guess you can use for-loop and break each number to digits (with str-split) and then add the arrays.
Consider the following example:
$arr = array(1, 11, 111, 113, 2, 21, 211, 213);
$chapter = array(); // this will be your result array
foreach($arr as $e) {
$digits = str_split($e);
$current = &$chapter;
foreach($digits as $d) {
if (!isset($current[$d]))
$current[$d] = array();
$current = &$current[$d];
}
}
Notice I used & to assign the new array to the original result one.
I know your array has missing key and not have to be sorted but I guess you can overcome it (filter and sort the array before)
Edited
After question has change this is the example code: (when key DATA is for the text you want and key CHILDREN for the next elements)
$arr = array(1 => "text1", 10 => "text10", 11 => "text11", 101 => "text101", 1011 => "text1011", 10123 => "text10123", 2 => "text2", 20 => "text20", 201 => "text201", 2011 => "text2011", 20111 => "text20111");
$chapter = array();
foreach($arr as $key => $val) {
$digits = str_split(substr($key, 0, 4)); // if 4 digits is the max depth
$current = &$chapter;
foreach($digits as $d) {
if (!isset($current["CHILDREN"][$d]))
$current["CHILDREN"][$d] = array();
$current = &$current["CHILDREN"][$d];
}
$current["DATA"] = $val;
}
I have five strings:
$array_key = "f_name, f_qty, f_price, f_cur_date";
$food_name = "Meal for 2, Four Seasons Pizza, Lunch Deal, Pepsi";
$food_qty = "1, 3, 5, 7";
$food_price = "10, 30, 50, 70";
$food_userId = "1, 2, 3, 4";
I need some array like this:
Array (
[0] => Array (
[f_name] => Meal for 2
[f_qty] => 1
[f_price] => 10
[f_cur_date] => 1
)
[1] => Array (
[f_name] => Four Seasons Pizza
[f_qty] => 3
[f_price] => 30
[f_cur_date] => 2
)
[2] => Array (
[f_name] => Lunch Deal
[f_qty] => 5
[f_price] => 50
[f_cur_date] => 3
)
[3] => Array (
[f_name] => Pepsi
[f_qty] => 7
[f_price] => 70
[f_cur_date] => 4
))
I convert strings to array with "explode":
$array_key_parts = explode(",",$array_key);
$food_name_parts = explode(",",$food_name);
$food_qty_parts = explode(",",$food_qty);
$food_price_parts = explode(",",$food_price);
$food_price_parts = explode(",",$food_price);
But don't know how to customize it further.
Basically, I'm getting this strings from query GROUP_CONCAT to use it in fullcalendar.js.
You can make an array using array_map function like below :
$food_name_parts = explode(",",$food_name);
$food_qty_parts = explode(",",$food_qty);
$food_price_parts = explode(",",$food_price);
$array_key_parts = explode(",",$array_key);
$myarray = array_map(function ($f_name, $f_qty, $f_price) {
return compact('f_name','f_qty','f_price');
}, $food_name_parts, $food_qty_parts, $food_price_parts);
echo "<pre>";
print_r($myarray);
I i'm developing php application. I have used Google Chart API for display charts.
I have select and returned necessary data for chart.
I got following array as my output.
print_r($output);
//Out put
Array
(
[0] => Array
(
[month] => April
[sec_id] => 2
[sec_name] => Commerce
[count] => 1
)
[1] => Array
(
[month] => June
[sec_id] => 2
[sec_name] => Commerce
[count] => 3
)
[2] => Array
(
[month] => July
[sec_id] => 2
[sec_name] => Commerce
[count] => 1
)
[3] => Array
(
[month] => August
[sec_id] => 4
[sec_name] => Science
[count] => 3
)
[4] => Array
(
[month] => August
[sec_id] => 3
[sec_name] => Maths
[count] => 2
)
[5] => Array
(
[month] => August
[sec_id] => 1
[sec_name] => Art
[count] => 2
)
[6] => Array
(
[month] => August
[sec_id] => 2
[sec_name] => Commerce
[count] => 2
)
)
print_r(json_encode($output)); // return above array as output
I request above data using ajax ( data type is JSON)
I want to return data as bellow to generate google chart.
[
['Month', 'Art', 'Commerce', 'Maths', 'Sience'],
['April', '', 2, '', ''],
['June', '', 3, '', ''],
['July', '', 1, '', ''],
['August', 2, 2, 3, 3]
]
I tried this this code
$output = array();
$output[0] = array('Month', 'Art', 'Commerce', 'Maths', 'Science');
foreach($records as $key=> $record){
$art =''; $commerce =''; $maths=''; $science='';
if($record['sec_id'] == 1){
$art = $record['count'];
}else if($record['sec_id'] == 2){
$commerce = $record['count'];
}else if($record['sec_id'] == 3){
$maths = $record['count'];
}else if($record['sec_id'] == 4){
$science = $record['count'];
}
$output[++$key] = array(0 => $record['month'], 1 => $art, 2 => $commerce, 3 => $maths, 4 => $science);
}
function super_unique($array){
$result = array_map("unserialize", array_unique(array_map("serialize", $array)));
foreach ($result as $key => $value){
if ( is_array($value)){
$result[$key] = super_unique($value);
}
}
return $result;
}
$output = super_unique($output);
Out put was
[["Month","Art","Commerce","Maths","Science"],["April","","1"],["June","","3"],["July","","1"],{"0":"August","1":"","4":"3"},{"0":"August","1":"","3":"2"},["August","2",""],["August","","2"]]
This is pretty straightforward to loop through and reorganize, particularly since your sec_ids match up nicely with the array indices.
Example:
$temp = array();
$output = array(
array('Month', 'Art', 'Commerce', 'Maths', 'Science')
);
foreach ($records as $record) {
$month = $record["month"];
$sec_id = $record["sec_id"];
$count = $record["count"];
if (!isset($temp[$month])) {
$temp[$month] = array_fill(0, 5, '');
}
$temp[$month][0] = $month;
$temp[$month][$sec_id] += $count;
}
$output = array_merge($output, array_values($temp));
echo json_encode($output);
Output:
[["Month","Art","Commerce","Maths","Science"],["April","",2,"",""],["June","",3,"",""],["July","",1,"",""],["August",2,2,2,3]]
Let's rethink your algorithm. As you go through each element in records, we need to ask two things: what data are we pulling out and what do we want to do with it?
The first question is simple: we're just pulling out the value 'count'.
The second question is going to determine our algorithm. What we want to do is take that 'count' value, and stick it a particular spot in our ourpur array.
Looking at the output array as a table, we can see that the desired position of 'count' is determined by the 'month' field (which determines the row) and by the 'sec_id'/'sec_name' fields (which determine the column). So what you want your loop to look like is this...
foreach($records as $record)
{
$output[$record['month']][$record['sec_id']] = $record['count']
}
The first caveat to this is that for each unique month, you do still need to create and initialize the sub-array, and you must do it only once. So, the loop becomes.
foreach($records as $record)
{
if(!is_array($output[$record['month']]))
$output[$record['month']] = array(0 => $record['month'], 1 => '', 2 => '', 3 => '', 4 => '');
$output[$record['month']][$record['sec_id']] = $record['count']
}
Finally, we used the actual month name as the keys in the top-level array. To comply with the numeric-only keys specified in your desired output, we can ditch those keys with the following piece of code.
$output = array_values($output)
If I'm right in thinking you were trying to use super_unique() to combine rows with the same month, that's not what it was doing at all. Firstly, array_unique() doesn't combine rows, it eliminates duplicates. Since you were comparing serialized rows, rather than just looking at the month field, none of your rows were duplicates, so that function was doing nothing. Furthermore, since several of your array fields were set to '', the serialize/unserialize process was actually causing those fields to get dropped, which is why you were ending up with sub-arrays of less than five elements, and with associative keys.
I've got the following array, containing ordered but non consecutive numerical keys:
Array
(
[4] => 2
[5] => 3
[6] => 1
[7] => 2
[8] => 1
[9] => 1
[10] => 1
)
I need to split the array into 2 arrays, the first array containing the keys below 5, and the other array consisting of the keys 5 and above. Please note that the keys may vary (e.g. 1,3,5,10), therefore I cannot use array_slice since I don't know the offset.
Do you know any simple function to accomplish this, without the need of using a foreach ?
Just found out array_slice has a preserve_keys parameter.
$a = [
4 => 2,
5 => 3,
6 => 1,
7 => 2,
8 => 1,
9 => 1,
10 => 1
];
$desired_slice_key = 5;
$slice_position = array_search($desired_slice_key, array_keys($a));
$a1 = array_slice($a, 0, $slice_position, true);
$a2 = array_slice($a, $slice_position, count($a), true);
you could use array_walk, passing in the arrays you wish to add the keys to by reference using the use keyword - something along the lines of this should work:
$splitArray = [1 => 2, 3 => 1, 5 => 2, 7 => 1, 9 => 3, 10 => 1];
$lt5 = [];
$gt5 = [];
array_walk($splitArray, function(&$val, $key) use (&$lt5, &$gt5) {
$key < 5 ? $lt5[] = $key : $gt5[] = $key;
});
var_dump($lt5, $gt5);
I have an array
Array(
[0] => Array
(
[0] => 33
[user_id] => 33
[1] => 3
[frame_id] => 3
)
[1] => Array
(
[0] => 33
[user_id] => 33
[1] => 3
[frame_id] => 3
)
[2] => Array
(
[0] => 33
[user_id] => 33
[1] => 8
[frame_id] => 8
)
[3] => Array
(
[0] => 33
[user_id] => 33
[1] => 3
[frame_id] => 3
)
[4] => Array
(
[0] => 33
[user_id] => 33
[1] => 3
[frame_id] => 3
)
)
As you can see key 0 is the same as 1, 3 and 4. And key 2 is different from them all.
When running the array_unique function on them, the only left is
Array (
[0] => Array
(
[0] => 33
[user_id] => 33
[1] => 3
[frame_id] => 3
)
)
Any ideas why array_unique isn't working as expected?
It's because array_unique compares items using a string comparison. From the docs:
Note: Two elements are considered
equal if and only if (string) $elem1
=== (string) $elem2. In words: when the string representation is the same.
The first element will be used.
The string representation of an array is simply the word Array, no matter what its contents are.
You can do what you want to do by using the following:
$arr = array(
array('user_id' => 33, 'frame_id' => 3),
array('user_id' => 33, 'frame_id' => 3),
array('user_id' => 33, 'frame_id' => 8)
);
$arr = array_intersect_key($arr, array_unique(array_map('serialize', $arr)));
//result:
array
0 =>
array
'user_id' => int 33
'user' => int 3
2 =>
array
'user_id' => int 33
'user' => int 8
Here's how it works:
Each array item is serialized. This
will be unique based on the array's
contents.
The results of this are run through array_unique,
so only arrays with unique
signatures are left.
array_intersect_key will take
the keys of the unique items from
the map/unique function (since the source array's keys are preserved) and pull
them out of your original source
array.
Here's an improved version of #ryeguy's answer:
<?php
$arr = array(
array('user_id' => 33, 'tmp_id' => 3),
array('user_id' => 33, 'tmp_id' => 4),
array('user_id' => 33, 'tmp_id' => 5)
);
# $arr = array_intersect_key($arr, array_unique(array_map('serialize', $arr)));
$arr = array_intersect_key($arr, array_unique(array_map(function ($el) {
return $el['user_id'];
}, $arr)));
//result:
array
0 =>
array
'user_id' => int 33
'tmp_id' => int 3
First, it doesn't do unneeded serialization. Second, sometimes attributes may be different even so id is the same.
The trick here is that array_unique() preserves the keys:
$ php -r 'var_dump(array_unique([1, 2, 2, 3]));'
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[3]=>
int(3)
}
This let's array_intersect_key() leave the desired elements.
I've run into it with Google Places API. I was combining results of several requests with different type of objects (think tags). But I got duplicates, since an object may be put into several categories (types). And the method with serialize didn't work, since the attrs were different, namely, photo_reference and reference. Probably these are like temporary ids.
array_unique() only supports multi-dimensional arrays in PHP 5.2.9 and higher.
Instead, you can create a hash of the array and check it for unique-ness.
$hashes = array();
foreach($array as $val) {
$hashes[md5(serialize($val))] = $val;
}
array_unique($hashes);
array_unique deosn't work recursive, so it just thinks "this are all Arrays, let's kill all but one... here we go!"
Quick Answer (TL;DR)
Distinct values may be extracted from PHP Array of AssociativeArrays using foreach
This is a simplistic approach
Detailed Answer
Context
PHP 5.3
PHP Array of AssociativeArrays (tabluar composite data variable)
Alternate name for this composite variable is ArrayOfDictionary (AOD)
Problem
Scenario: DeveloperMarsher has a PHP tabular composite variable
DeveloperMarsher wishes to extract distinct values on a specific name-value pair
In the example below, DeveloperMarsher wishes to get rows for each distinct fname name-value pair
Solution
example01 ;; DeveloperMarsher starts with a tabluar data variable that looks like this
$aodtable = json_decode('[
{
"fname": "homer"
,"lname": "simpson"
},
{
"fname": "homer"
,"lname": "jackson"
},
{
"fname": "homer"
,"lname": "johnson"
},
{
"fname": "bart"
,"lname": "johnson"
},
{
"fname": "bart"
,"lname": "jackson"
},
{
"fname": "bart"
,"lname": "simpson"
},
{
"fname": "fred"
,"lname": "flintstone"
}
]',true);
example01 ;; DeveloperMarsher can extract distinct values with a foreach loop that tracks seen values
$sgfield = 'fname';
$bgnocase = true;
//
$targfield = $sgfield;
$ddseen = Array();
$vout = Array();
foreach ($aodtable as $datarow) {
if( (boolean) $bgnocase == true ){ #$datarow[$targfield] = #strtolower($datarow[$targfield]); }
if( (string) #$ddseen[ $datarow[$targfield] ] == '' ){
$rowout = array_intersect_key($datarow, array_flip(array_keys($datarow)));
$ddseen[ $datarow[$targfield] ] = $datarow[$targfield];
$vout[] = Array( $rowout );
}
}
//;;
print var_export( $vout, true );
Output result
array (
0 =>
array (
0 =>
array (
'fname' => 'homer',
'lname' => 'simpson',
),
),
1 =>
array (
0 =>
array (
'fname' => 'bart',
'lname' => 'johnson',
),
),
2 =>
array (
0 =>
array (
'fname' => 'fred',
'lname' => 'flintstone',
),
),
)
Pitfalls
This solution does not aggregate on fields that are not part of the DISTINCT operation
Arbitrary name-value pairs are returned from arbitrarily chosen distinct rows
Arbitrary sort order of output
Arbitrary handling of letter-case (is capital A distinct from lower-case a ?)
See also
php array_intersect_key
php array_flip
function array_unique_recursive($array)
{
$array = array_unique($array, SORT_REGULAR);
foreach ($array as $key => $elem) {
if (is_array($elem)) {
$array[$key] = array_unique_recursive($elem);
}
}
return $array;
}
Doesn't that do the trick ?
`
$arr = array(
array('user_id' => 33, 'tmp_id' => 3),
array('user_id' => 33, 'tmp_id' => 4),
array('user_id' => 33, 'tmp_id' => 3),
array('user_id' => 33, 'tmp_id' => 4),
);
$arr1 = array_unique($arr,SORT_REGULAR);
echo "<pre>";
print_r($arr1);
echo "</pre>";
Array(
[0] => Array(
[user_id] => 33
[tmp_id] => 3
)
[1] => Array(
[user_id] => 33
[tmp_id] => 4
)
)
`