PHP create array from another array - php

I have an array which I have received from an API.
object(stdClass)#19498 (4) {
["success"]=>
bool(true)
["quoteId"]=>
int(0011)
["abcValue"]=>
float(00)
["priceResponse"]=>
array(4) {
[0]=>
object(stdClass)#19502 (9) {
["priceId"]=>
int(1263)
["fPrice"]=>
float(37.14)
["grossPrice"]=>
float(44.7)
["priceType"]=>
string(2) "ABC"
}
[1]=>
object(stdClass)#19501 (10) {
["priceId"]=>
int(1263)
["fPrice"]=>
float(37.14)
["grossPrice"]=>
float(44.7)
["priceType"]=>
string(2) "ABC"
}
[2]=>
object(stdClass)#19500 (8) {
["priceId"]=>
int(1266)
["fPrice"]=>
float(550.14)
["grossPrice"]=>
float(544.7)
["priceType"]=>
string(2) "DEF"
}
}
}
I want to loop through the array to add another object in PriceResponse i.e customPrice and also delete some objects from the array like fPrice, priceType etc. The best way I figured to do this was to create another array. However I can't seem to get it working:
PHP:
$output_array = json_decode($output);
$modified_array = array();
$priceResultArray = array();
foreach($output_array as $j => $item) {
foreach($output_array->priceResponse as $i => $field) {
$percent = $field->grossPrice * 10 / 100;
$customPrice = $field->grossPrice + $percent;
$priceResultArray['priceId'] = $field->priceId;
$priceResultArray['customPrice'] = $customPrice;
}
$modified_array['success'] = $output_array->success;
$modified_array['quoteId'] = $output_array->quoteId;
$modified_array['priceResponse'] = $priceResultArray;
}
var_dump($modified_array);
This is the output of the modified array - it only shows the last result of the priceResultArray:
array(3) {
["success"]=>
bool(true)
["quoteId"]=>
int(0011)
["priceResult"]=>
array(5) {
["priceId"]=>
int(1266)
["customPrice"]=>
float(599.17)
}
}
Any pointers would be appreciated.

You don't need the outer loop. $output_array is a single object, not an array. You're looping over the properties, but never doing anything with $j or $item.
And instead of creating a new array, you can simply modify the objects in the original priceResponse array.
$output_array = json_decode($output);
foreach ($output_array->priceResponse as $field) {
$percent = $field->grossPrice * 10 / 100;
$customPrice = $field->grossPrice + $percent;
$field->customPrice = $customPrice;
unset($field->fPrice);
unset($field->priceType);
unset($field->grossPrice);
}

You have such output because you put values inside the same keys within your loop.
You should create new object on each loop interation.
Checkout this code:
$output_array = json_decode($output);
$modified_array = array();
$priceResultArray = array();
foreach($output_array as $j => $item) {
foreach($output_array->priceResponse as $i => $field) {
$percent = $field->grossPrice * 10 / 100;
$customPrice = $field->grossPrice + $percent;
$singlePriceResult = array();
$singlePriceResult['priceId'] = $field->priceId;
$singlePriceResult['customPrice'] = $customPrice;
$priceResultArray[] = $singlePriceResult;
}
$modified_array['success'] = $output_array->success;
$modified_array['quoteId'] = $output_array->quoteId;
$modified_array['priceResponse'] = $priceResultArray;
}
var_dump($modified_array);

Related

Unify quantities in one item

I have two arrays which have items and quantities and they are asociated by the index of the arrays. Example:
Items=XL,M,XL,S
Quantities=5,2,4,7
What I want to achieve is to remove the repetitive items and sum their quantities:
Items=XL,M,S
Quantities=9,2,7
$uniqueTallesTotalesC = array_unique($tallesTotalesC);
for($i=0;$i<Count($uniqueTallesTotalesC);$i++){
for($e=0;$e<Count($cantidadesTotalesC);$e++){
if($uniqueTallesTotalesC[$i]==$tallesTotalesC[$e] && $e > $i){
$cantidadesTotalesC[$i] = $cantidadesTotalesC[$i] + $cantidadesTotalesC[$e];
} else{
}
}
}
You can just blindly zip-merge them together with summation:
$items = explode(',', 'XL,M,XL,S');
$quantities = explode(',', '5,2,4,7');
if(count($items) !== count($quantities)){
throw new RuntimeException('Count mismatch');
}
$final = [];
for($i = 0; $i < count($items); $i++) {
if(!isset($final[$items[$i]])){
$final[$items[$i]] = 0;
}
$final[$items[$i]] += $quantities[$i];
}
var_dump($final);
Outputs:
array(3) {
["XL"]=>
int(9)
["M"]=>
int(2)
["S"]=>
int(7)
}
Demo: https://3v4l.org/6A5ZC
There's probably an autovivification that I'm missing that could simplify this greater.
I suggest you to create another array variable to hold the new items' quantities:
// I imagine these are your existing variables from your sample code
$tallesTotalesC = array('XL','M','XL','S');
$cantidadesTotalesC = array(5,2,4,7);
$uniqueTallesTotalesC = array_unique($tallesTotalesC);
// This will reset the indexes of the unique items array
$uniqueTallesTotalesC = array_values($uniqueTallesTotalesC);
// init a new quantities array with zeros
$uniqueCantidadesTotales = array_fill(0, count($uniqueTallesTotalesC), 0);
if (count($uniqueTallesTotalesC) == count($tallesTotalesC)) {
// all items are unique so no need to loop through and sum the quantities
$uniqueCantidadesTotales = $cantidadesTotalesC;
} else {
foreach($uniqueTallesTotalesC as $newIndex => $item) {
// get all indexes of the item in the old array
$oldIndexes = array_keys($tallesTotalesC, $item);
// for each of the index, get the sum the old quantity to the new quantity
foreach($oldIndexes as $oldIndex) {
$uniqueCantidadesTotales[$newIndex] += $cantidadesTotalesC[$oldIndex];
}
}
}
Hope it helps!

Adding to array from multiple foreach statements

I'm trying to add the dynamically generated variables $title and $price to the array $list.
This works to a certain degree. The code creates an array with the keys where they have a title and price value.
The price value is correct and different for each key. However, it seems that only the first title result is added, creating the following array (same title untill key 30)
[0]=> array(2) { ["title"]=> string(57) "Gibson Les Paul ** Nr.1 Gibson dealer ** 18 gitaarwinkels" ["price"]=> string(25) " € 300,00 " } [1]=> array(2) { ["title"]=> string(57) "Gibson Les Paul ** Nr.1 Gibson dealer ** 18 gitaarwinkels" ["price"]=> string(25) " € 100,00 " }
Looking at the code I think it is because the first foreach loop is only executing the second one.
I know the correct values for $title are there, because when I isolate the title foreach loop like this:
foreach ($titlehit as $titles) {
$title = $titles->nodeValue;
echo "$title";
}
30 different $title result are displayed
$url = "https://url.com";
$html = new DOMDocument();
#$html->loadHtmlFile($url);
$xpath = new DOMXPath($html);
$titlehit = $xpath->query("//span[#class='mp-listing-title']");
$pricehit = $xpath->query("//span[#class='price-new']");
$list = array();
$i = 0;
foreach ($titlehit as $titles) {
foreach ($pricehit as $prices) {
if ($i >=5 && $i <=35) {
$title = $titles->nodeValue;
$price = $prices->nodeValue;
$list[] = array(
'title' => $title,
'price' => $price
);
}
$i++;
}
}
How can I get the array $list to hold both the correct title and price values? Thanks for your help.
Assuming that for each title, there is one price i.e there is a 1:1 title-to-price ratio in the corresponding arrays, you will only need 1 loop.
$list = array();
$i = 0; // initialize
// Assuming $titlehit AND $pricehit have the same number of elements
foreach ($titlehit as $titles) {
// Assuming $pricehit is a simple array. If it is an associative array, we need to use the corresponding key as the index instead of $i. We'll get to this once you can confirm the input.
$prices = $pricehit[$i];
// Not entirely sure why you need this condition.
if ($i >=5 && $i <=35) {
$title = $titles->nodeValue;
$price = $prices->nodeValue;
$list[] = array(
'title' => $title,
'price' => $price
);
}
$i++;
}
Not exactly enough code here to know for sure but it looks like you need to reset your iterator $i with each iteration of your foreach loop:
$list = array();
foreach ($titlehit as $titles) {
$i = 0;
foreach ($pricehit as $prices) {
if ($i >=5 && $i <=35) {
$title = $titles->nodeValue;
$price = $prices->nodeValue;
$list[] = array(
'title' => $title,
'price' => $price
);
}
$i++;
}
}

How to create an array based on value in PHP?

I have an array like this
Array
(
[0] => 123_dr_for_ma_on_2352015_2nd Shift_(08-29-2015_11-31).pdf
[1] => 123_dr_for_ma_on_2352015_2nd Shift_(08-29-2015_11-30).pdf
[2] => 123_bms_for__on__(10-06-2015_18-36).pdf
)
I want to convert this into multidimensional array based on its value such
as
Array
(
[dr] => Array
(
[0] => 123_dr_for_ma_on_2352015_2nd Shift_(08-29-2015_11-31).pdf
[1] => 123_dr_for_ma_on_2352015_2nd Shift_(08-29-2015_11-30).pdf
)
[bms] => Array
(
[0] => 123_bms_for__on__(10-06-2015_18-36).pdf
)
)
based on name after first underscore (bms,dr) like....... Please help me to achieve this
I would do the following:
$newArray = array();
foreach ($array as $key => $value) {
$parts = explode('_', $value);
$newArray[$parts[1]][] = $value;
}
print_r($newArray);
To solve this without a loop, it would be smart to use a function along with built in Array Filter function.
Here's another possible solution - which seems a little cooler I suppose;
<?php
// ####################
// GLOBAL VARIABLES DEFINITION
// ####################
// Store Pattern Here = Used to Define Array at the end
global $Array_IDs;
$Array_IDs = array();
// Store Variables With Header Pattern (ID) in this area
global $Array_Values;
$Array_Values = array();
// ####################
// FUNCTION DEFINITION
// ####################
// FUNCTION TO SPLIT ARRAY
function Get_ID($variable){
// ACCESS GLOBALS
global $Array_IDs;
global $Array_Values;
// GET CURRENT VARIBALE - EXPLODE TO EXTRACT PATTERN AS ID
$Temp_Parts = explode("_", $variable);
// CHECK IF IDENTIFIER IS ALREADY FOUND (STORED IN ARRAY_ID)
if (in_array($Temp_Parts[1], $Array_IDs)){
// ID ALREADY HAS SUB-ARRAY CREATED
// JUST APPEND VARIABLE
$Array_Values[$Temp_Parts[1]][] = $variable;
}else{
// ADD ID TO Array_IDs
$Array_IDs[] = $Temp_Parts[1];
// Create New ARRAY with HEADER AS PATTERN - ID
$Array_Values[$Temp_Parts[1]][] = $variable;
}
}
// ####################
// CODE STARTS HERE == ONLY THREE LINES ;)
// ####################
$Start_Array = array('123_dr_for_ma_on_2352015_2nd Shift_(08-29-2015_11-31).pdf','123_dr_for_ma_on_2352015_2nd Shift_(08-29-2015_11-30).pdf','123_bms_for__on__(10-06-2015_18-36).pdf');
array_filter($Start_Array,"Get_ID");
print_r($Array_Values);
?>
Give it a try and let me know how it goes, the output is as requested ;)
You can use array_reduce function and regex matching for elegant & lesser code.
$array = array(
'0'=>'123_dr_for_ma_on_2352015_2nd Shift_(08-29-2015_11-31).pdf',
'1'=>'123_dr_for_ma_on_2352015_2nd Shift_(08-29-2015_11-30).pdf',
'2'=>'123_bms_for__on__(10-06-2015_18-36).pdf'
);
$result = array_reduce($array, function($prod, $current){
preg_match('/(?<=^123_)\w+(?=_for\w+)/',$current,$match);
$prod[$match[0]][] = $current;
return $prod;
}, []);
Will produce the following result.
array(2) {
[0]=>
string(57) "123_dr_for_ma_on_2352015_2nd Shift_(08-29-2015_11-31).pdf"
[1]=>
string(57) "123_dr_for_ma_on_2352015_2nd Shift_(08-29-2015_11-30).pdf"
}
array(1) {
[0]=>
string(39) "123_bms_for__on__(10-06-2015_18-36).pdf"
}
Using square bracket require PHP 5.4 above, you can replace with array() instead for lower version of PHP.
please find below code as per your requirement.
<?php
$array = array(
'0'=>'123_dr_for_ma_on_2352015_2nd Shift_(08-29-2015_11-31).pdf',
'1'=>'123_dr_for_ma_on_2352015_2nd Shift_(08-29-2015_11-30).pdf',
'2'=>'123_bms_for__on__(10-06-2015_18-36).pdf'
);
$dr_array = array();
$bms_array = array();
foreach($array as $val){
$str_explode = explode("_",$val);
if($str_explode[1]=="dr"){
$dr_array[] = $val;
}
else if($str_explode[1]=="bms"){
$bms_array[] = $val;
}
}
var_dump($dr_array);
var_dump($bms_array);
?>
Output :
array(2) {
[0]=>
string(57) "123_dr_for_ma_on_2352015_2nd Shift_(08-29-2015_11-31).pdf"
[1]=>
string(57) "123_dr_for_ma_on_2352015_2nd Shift_(08-29-2015_11-30).pdf"
}
array(1) {
[0]=>
string(39) "123_bms_for__on__(10-06-2015_18-36).pdf"
}
Thanks.
$basicArray = array(); //It Stores All The Elements
$firstArray = array(); //It will store array elements of first type
$secondArray = array(); //It will store array elements of second type
for($i = 0; $i < count($basicArray); $i++)
{
$elementArray = explode("_", $basicArray[i]);
if($elementArray[1] == "dr")
array_push($firstArray, $basicArray[i]);
else if($elementArray[1] == "bms")
array_push($secondArray, $basicArray[i]);
}
$finalArray = array();
array_push($finalArray, $firstArray, $secondArray);

How to create a nested array out of an array in PHP

Say, we have an array: array(1,2,3,4,...)
And I want to convert it to:
array(
1=>array(
2=>array(
3=>array(
4=>array()
)
)
)
)
Can anybody help?
Thanks
EDIT It would be good to have the solution with iterations.
$x = count($array) - 1;
$temp = array();
for($i = $x; $i >= 0; $i--)
{
$temp = array($array[$i] => $temp);
}
You can simply make a recursive function :
<?php
function nestArray($myArray)
{
if (empty($myArray))
{
return array();
}
$firstValue = array_shift($myArray);
return array($firstValue => nestArray($myArray));
}
?>
Well, try something like this:
$in = array(1,2,3,4); // Array with incoming params
$res = array(); // Array where we will write result
$t = &$res; // Link to first level
foreach ($in as $k) { // Walk through source array
if (empty($t[$k])) { // Check if current level has required key
$t[$k] = array(); // If does not, create empty array there
$t = &$t[$k]; // And link to it now. So each time it is link to deepest level.
}
}
unset($t); // Drop link to last (most deep) level
var_dump($res);
die();
Output:
array(1) {
[1]=> array(1) {
[2]=> array(1) {
[3]=> array(1) {
[4]=> array(0) {
}
}
}
}
}
I think the syntax for the multidimensional array you want to create would look like the following.
$array = array(
'array1' => array('value' => 'another_value'),
'array2' => array('something', 'something else'),
'array3' => array('value', 'value')
);
Is this what you're looking for?
You can also use this array library to do that in just one line:
$array = Arr::setNestedElement([], '1.2.3.4', 'value');

PHP unique array by value?

I have an array in PHP that looks like this:
[0]=>
array(2) {
["name"]=>
string(9) "My_item"
["url"]=>
string(24) "http://www.my-url.com/"
}
[1]=>
array(2) {
["name"]=>
string(9) "My_item"
["url"]=>
string(24) "http://www.my-url2.com/"
}
The two values in "name" are the same in this two items. I want to sort out duplicates like this.
How do I create an unique array by checking the "name" value?
basically
$unique_array = [];
foreach($your_array as $element) {
$hash = $element[field-that-should-be-unique];
$unique_array[$hash] = $element;
}
$result = array_values($unique_array);
Serialisation is very useful for simplifying the process of establishing the uniqueness of a hierarchical array. Use this one liner to retrieve an array containing only unique elements.
$unique = array_map("unserialize", array_unique(array_map("serialize", $input)));
Please find this link useful, uses md5 hash to examine the duplicates:
http://www.phpdevblog.net/2009/01/using-array-unique-with-multidimensional-arrays.html
Quick Glimpse:
/**
* Create Unique Arrays using an md5 hash
*
* #param array $array
* #return array
*/
function arrayUnique($array, $preserveKeys = false)
{
// Unique Array for return
$arrayRewrite = array();
// Array with the md5 hashes
$arrayHashes = array();
foreach($array as $key => $item) {
// Serialize the current element and create a md5 hash
$hash = md5(serialize($item));
// If the md5 didn't come up yet, add the element to
// to arrayRewrite, otherwise drop it
if (!isset($arrayHashes[$hash])) {
// Save the current element hash
$arrayHashes[$hash] = $hash;
// Add element to the unique Array
if ($preserveKeys) {
$arrayRewrite[$key] = $item;
} else {
$arrayRewrite[] = $item;
}
}
}
return $arrayRewrite;
}
$uniqueArray = arrayUnique($array);
var_dump($uniqueArray);
See the working example here:
http://codepad.org/9nCJwsvg
Simple Solution:
/**
* #param $array
* #param null $key
* #return array
*/
public static function unique($array,$key = null){
if(null === $key){
return array_unique($array);
}
$keys=[];
$ret = [];
foreach($array as $elem){
$arrayKey = (is_array($elem))?$elem[$key]:$elem->$key;
if(in_array($arrayKey,$keys)){
continue;
}
$ret[] = $elem;
array_push($keys,$arrayKey);
}
return $ret;
}
function unique_multidim_array($array, $key) {
$temp_array = array();
$i = 0;
$key_array = array();
foreach($array as $val) {
if (!in_array($val[$key], $key_array)) {
$key_array[$i] = $val[$key];
$temp_array[$i] = $val;
}
$i++;
}
return $temp_array;
}
$result = unique_multidim_array($visitors,'ip');
Given that the keys on the array (0,1) do not seem to be significant a simple solution would be to use the value of the element referenced by 'name' as the key for the outer array:
["My_item"]=>
array(2) {
["name"]=>
string(9) "My_item"
["url"]=>
string(24) "http://www.my-url.com/"
}
...and if there is only one value other than the 'name' why bother with a nested array at all?
["My_item"]=>"http://www.my-url.com/"

Categories