php - Iterate through array and order by dependencies - php

I was wondering if there is a known class/functions or any tutorials out there that can help in ordering an array by its dependency (stored as there value of the key pair).
i.e. (please note these are not actual dependancies)
Array
(
[blueimp-canvas-to-blob] => Array
(
)
[blueimp-load-image] => Array
(
[0] => jquery
)
[blueimp-tmpl] => Array
(
[0] => jquery
[1] => blueimp-load-image
)
[jquery] => Array
(
)
[blueimp-file-upload] => Array
(
[0] => jquery
[1] => blueimp-tmpl
[2] => blueimp-load-image
[3] => blueimp-canvas-to-blob
)
)
would be ordered as:
Array
(
[blueimp-canvas-to-blob] => Array
(
)
[jquery] => Array
(
)
[blueimp-load-image] => Array
(
[0] => jquery
)
[blueimp-tmpl] => Array
(
[0] => jquery
[1] => blueimp-load-image
)
[blueimp-file-upload] => Array
(
[0] => jquery
[1] => blueimp-tmpl
[2] => blueimp-load-image
[3] => blueimp-canvas-to-blob
)
)
any help would be greatly appreciated

Managed to figure this out (i think):
private function orderItems(){
while( ! empty( $this->order ) ) {
$item = array_splice( $this->order, 0, 1 );
$dependencies = end( $item );
$name = key( $item );
if( empty( $dependencies ) ) {
$this->ordered[$name] = $dependencies;
} else {
$satisafied = true;
foreach( $dependencies as $dependency ) {
if( isset( $this->order[$dependency] ) ) $satisafied = false;
}
if( $satisafied ) {
$this->ordered[$name] = $dependencies;
} else {
$this->order = $this->order + $item;
}
}
}
}
here if anyone else wants something simular

Related

How to store array with array_push() outside loop?

I have an array, when i tried to print_r was just like this :
Array ( [user_id] => Erick ) Array ( [user_id] => Baldi) Array([user_id]=> Bintang ) Array ( [user_id] => Bagas ) Array ( [user_id] => Baim )
My Expected output just like :
Array (
Array (
[user_id] => Erick
)
Array (
[user_id] => Baldi
)
Array (
[user_id] => Bintang
)
Array (
[user_id] => Bagas
)
Array (
[user_id] => Baim
)
)
Anyone here have an idea ? I'm stuck with this.
This my php code :
public function get_userid() {
// $action = $this->input->post('action');
$customerField = $this->input->post('customer');
$projectField = $this->input->post('project');
$user_roleField = $this->input->post('role');
for ($i=0; $i<count($customerField); $i++) {
for ($j=0; $j<count($projectField); $j++) {
for ($k=0; $k<count($user_roleField); $k++) {
array_push($test, $this->get_array_push($customerField[$i], $projectField[$j], $user_roleField[$k]));
}
}
}
}
public function get_array_push($customer, $project, $user_role) {
$query = $this->db->query("SELECT user_id
FROM `ixt_user_project_list`
LEFT JOIN ixt_user_type ON ixt_user_project_list.user_type = ixt_user_type.user_type
WHERE ixt_user_project_list.user_cust_id ='".$customer."'
AND ixt_user_project_list.user_project_id ='".$project."'
AND ixt_user_type.user_owner ='".$user_role."'")->result_array();
//Filter null array
foreach ($query as $key => $value) {
print_r($value);
}
}
And this is my initial query value :
Array ( [0] => Array ( [user_id] => Erick ) ) Array ( ) Array ( ) Array ( ) Array ( ) Array ( ) Array ( [0] => Array ( [user_id] => Baldi ) [1] => Array ( [user_id] => Bintang ) ) Array ( [0] => Array ( [user_id] => Bagas ) [1] => Array ( [user_id] => Baim ) )
As #scaisEdge wrote - its happening because you use the print_r inside the foreach loop.
If you want to filter null result you can use array-filter as:
$arr = array(array("user_id" => "aaa"), null, array(), array("user_id" => null), array("otherField" => "bbb"));
$filterdResult = array_filter($arr, function($elem) {
return ($elem && array_key_exists("user_id", $elem) && !is_null($elem["user_id"]));
});
Now you can just do print_r($filterdResult );
This will output:
Array
(
[0] => Array
(
[user_id] => aaa
)
)
Edited: After setting your new input as:
$query = array(array(array("user_id" => "aaa"), null, array(), array("user_id" => null)), array(array("user_id" => "ccc"), null, array(),array("user_id" =>"ddd")));
You can use the following:
$res = array();
//Filter null array
foreach ($query as $key => $value) {
array_push($res, array_filter($value, function($elem) {
return ($elem && array_key_exists("user_id", $elem) && !is_null($elem["user_id"])); }));
}
print_r($res);
Which output:
Array
(
[0] => Array
(
[0] => Array
(
[user_id] => aaa
)
)
[1] => Array
(
[0] => Array
(
[user_id] => ccc
)
[3] => Array
(
[user_id] => ddd
)
)
)
From here flatten is available if needed.
#David Winder I tried to combine as your suggesstion with the null array filter.
$res = array();
//Filter null array
foreach ($query as $key => $value) {
if (!is_null($value)) {
$res[] = $value;
//print_r($res);
}
}
But when i print_r($res) inside the foreach loop the result became duplicate array inside all of the array value.

How to create the perfect array using Push in array (woocommerce re-create cart)

I'm looking to create an array that would look like this
$cart = array([product_id] array([size], [quantity]));
Here is the info I'm having on my page :
86253//35//1
86253//36//1
86253//38//2
86253//39//3
86253//40//2
86245//36//7
86245//39//4
$product_id // $size // $quantity
and here is how I get it :
foreach($items as $item => $values) {
$_product = wc_get_product( $values['data']->get_id());
if($_product->post_type == 'product_variation'){
echo $_product->parent_id; echo '//'; echo $values['variation']['taille'];
echo '//'; echo $values['quantity'];
}
}
how can I create my perfect array using push_array php function ?
You could try the following code:
// the array to store the data
$cart = array();
foreach($items as $item => $values)
{
$_product = wc_get_product( $values['data']->get_id());
if($_product->post_type == 'product_variation')
{
echo $_product->parent_id; echo '//'; echo $values['variation']['taille'];
echo '//'; echo $values['quantity'];
// create the new temporary array to save the data structure
$tmp = array( $_product->parent_id, array( $values['variation']['taille'], $values['quantity'] ) );
// add the tmp array to the storage array
array_push($cart, $tmp );
}
}
If you print out the "cart" array it will look this:
Array
(
[0] => Array
(
[0] => 86253
[1] => Array
(
[0] => 35
[1] => 1
)
)
[1] => Array
(
[0] => 86253
[1] => Array
(
[0] => 36
[1] => 1
)
)
[2] => Array
(
[0] => 86253
[1] => Array
(
[0] => 38
[1] => 2
)
)
)
EDIT:
That's not exactly what you wanted but it should also group the array data by the product id:
// the array to store the data
$cart = array();
foreach($items as $item => $values)
{
$_product = wc_get_product( $values['data']->get_id());
if($_product->post_type == 'product_variation')
{
echo $_product->parent_id; echo '//'; echo $values['variation']['taille'];
echo '//'; echo $values['quantity'];
// Check if the parent_id is already set as array key
if( !array_key_exists ( $_product->parent_id, $cart ) )
{
// use the parent_id as key
$cart[$_product->parent_id] = array();
}
// create the new temporary array
$tmp = array( $values['variation']['taille'], $values['quantity'] );
// add the tmp array to the $cart
array_push($cart[$_product->parent_id], $tmp );
}
}
If you print it out it should look like this:
Array
(
[86253] => Array
(
[0] => Array
(
[0] => 35
[1] => 1
)
[1] => Array
(
[0] => 36
[1] => 1
)
)
[86245] => Array
(
[0] => Array
(
[0] => 36
[1] => 7
)
[1] => Array
(
[0] => 39
[1] => 4
)
)
)

php array sum for same value

I have this array:
Array ( [0] =>
Array (
[0] => Array (
[07] => Array (
[2] => 352.9
[3] => 375737
[4] => 1000000002
) )
[1] => Array (
[07] => Array (
[2] => 362.1
[3] => 375797
[4] => 1000000002
) )
)
Array ( [1] =>
[0] => Array (
[08] => Array (
[2] => 305.7
[3] => 375857
[4] => 1000000002
) )
)
)
i need a final array sum for the key 07 ( is the month ) like this:
Array ( [0] =>
Array (
[0] => Array (
[07] => Array (
[2] => 3254.9 ( the sum of each 07 )
[3] => 6521545 ( the sum )
[4] => 98474916521621 ( the sum )
) )
)
Array ( [1] =>
[0] => Array (
[08] => Array (
[2] => 305.7 ( not summed cause month 08 is only one )
[3] => 375857 ""
[4] => 1000000002 ""
) )
)
)
Any help?
Here, try this - I'm sure it's neither a perfect nor optimal solution ( 3 foreach-es ), but it works on a reasonably large data set...
$inputArray is the multidimensional array with the data you provided, btw...
EDIT: Fixed version:
$result = array();
foreach( $inputArray as $subArray ) {
foreach ( $subArray as $subKey => $member ) {
if ( empty( $result[$subKey]) ) {
$result[$subKey] = $member;
} else {
foreach ( $member as $id => $subMember ) {
if ( empty( $result[$subKey][$id]) ) {
$result[$subKey][$id] = $subMember;
} else {
$result[$subKey][$id] += $subMember;
}
}
}
}
}
EDIT2: Since you changed the format of arrays, the solution is different:
Note: $array1 and $array2 are your "global" - predefined arrays.
$arrayWrapper = array_merge( ( array ) $array1, ( array ) $array2 );
$result = array();
foreach ( $arrayWrapper as $inputArray ) {
foreach( $inputArray as $subArray ) {
foreach ( $subArray as $subKey => $member ) {
if ( empty( $result[$subKey]) ) {
$result[$subKey] = $member;
} else {
foreach ( $member as $id => $subMember ) {
if ( empty( $result[$subKey][$id]) ) {
$result[$subKey][$id] = $subMember;
} else {
$result[$subKey][$id] += $subMember;
}
}
}
}
}
}
Tested it with your data, should work.
Cheers.

iterating over SimpleXML Objext PHP

Here is what my object looks like with print_r (this is an object returned by the PHP SDK for the Amazon Web Services Simple DB.
[GetAttributesResult] => CFSimpleXML Object
(
[Attribute] => Array
(
[0] => CFSimpleXML Object
(
[Name] => data_datein
[Value] => 2011-04-23
)
[1] => CFSimpleXML Object
(
[Name] => data_estatus
[Value] => 0
)
[2] => CFSimpleXML Object
(
[Name] => data_status
[Value] => 1
)
[3] => CFSimpleXML Object
(
[Name] => data_title
[Value] => Company Info
)
[4] => CFSimpleXML Object
(
[Name] => data_tags
[Value] => firsttag
)
[5] => CFSimpleXML Object
(
[Name] => data_tags
[Value] => secondtag
)
[6] => CFSimpleXML Object
(
[Name] => data_tags
[Value] => thirdtag
)
[7] => CFSimpleXML Object
(
[Name] => data_files
[Value] => company_info.flv
)
[8] => CFSimpleXML Object
(
[Name] => data_id
[Value] => 8993
)
)
)
I have a function that iterates over the GetAttributesResult Object and creates an associative array that makes it easy to reference my fields by their names. One of my Names is data_tags, which is repeated an unknown number of times. I would like to return data_tags as a simple indexed array of those values. Here's my function, which doesn't work.
function attrToArray($select) {
$results = array();
$x = 0;
foreach($select->body->GetAttributesResult as $result) {
foreach ($result as $field) {
if (array_key_exists($field,$results[$x])) {
$results[$x][ (string) $field->Name ][] = (string) $field->Value;
} else {
$results[$x][ (string) $field->Name ] = (string) $field->Value;
}
}
$x++;
}
return $results;
}
I don't know if this is the most elegant solution, but I don't see why it wouldn't work. array_key_exists doesn't return true. By mistake I was able to test as in_array($field-Name,$results[$x]) and that built the array of my repeated $field->Name values... but it also converted all of the other values into single item nested array... so it would seem that it returned true more than I thought it would have. Although the hyphen in there was by mistake I meant to use -> which doesn't return true... so I'm very confused by what is going on there. Here's the print_r to show what came back.
Array ( [0] => Array (
[data_datein] => 2011-04-23
[data_estatus] => 0
[data_status] => Array ( [0] => 1 )
[data_title] => Array ( [0] => Company Info )
[data_tags] => Array (
[0] => firsttag
[1] => secondtag
[2] => thirdtag )
[data_files] => Array ( [0] => company_info.flv )
[data_id] => Array ( [0] => 8993 ) ) )
Any pointers, suggestions or instruction on how I might handle this better... and at very least if someone can figure out how I can get to the above array without the nested arrays on the other non-redundant fields. Very much appreciated!
Here is the print_r() of $result
CFSimpleXML Object
(
[Attribute] => Array
(
[0] => CFSimpleXML Object
(
[Name] => data_datein
[Value] => 2011-04-23
)
[1] => CFSimpleXML Object
(
[Name] => data_estatus
[Value] => 0
)
[2] => CFSimpleXML Object
(
[Name] => data_title
[Value] => 0001 01 Company Name
)
[3] => CFSimpleXML Object
(
[Name] => data_status
[Value] => 1
)
[4] => CFSimpleXML Object
(
[Name] => data_tags
[Value] => good stuff
)
[5] => CFSimpleXML Object
(
[Name] => data_tags
[Value] => save tags
)
[6] => CFSimpleXML Object
(
[Name] => data_tags
[Value] => tagger works
)
[7] => CFSimpleXML Object
(
[Name] => data_files
[Value] => 0001_01_company_name.flv
)
[8] => CFSimpleXML Object
(
[Name] => data_id
[Value] => yFKwIxjIhH
)
)
)
and here is a print_r() of $field (iterated and separated by <hr> tags.)
CFSimpleXML Object
(
[Name] => data_datein
[Value] => 2011-04-23
)
<hr>CFSimpleXML Object
(
[Name] => data_estatus
[Value] => 0
)
<hr>CFSimpleXML Object
(
[Name] => data_title
[Value] => 0001 01 Company Name
)
<hr>CFSimpleXML Object
(
[Name] => data_status
[Value] => 1
)
<hr>CFSimpleXML Object
(
[Name] => data_tags
[Value] => good stuff
)
<hr>CFSimpleXML Object
(
[Name] => data_tags
[Value] => save tags
)
<hr>CFSimpleXML Object
(
[Name] => data_tags
[Value] => tagger works
)
<hr>CFSimpleXML Object
(
[Name] => data_files
[Value] => 0001_01_company_name.flv
)
<hr>CFSimpleXML Object
(
[Name] => data_id
[Value] => yFKwIxjIhH
)
In the AWS PHP SDK, you can use to_json(), to_stdClass() and even to_array() to get back other data types from a CFSimpleXML object. Also with SimpleXML objects, typecasting is key!
PHP has an object called ArrayObject which is more-or-less an OOP version of an array. When you call CFSimpleXML->to_array(), you get back a CFArray object, which wraps the native ArrayObject object with extra functionality.
$array = $response->body->GetAttributesResult->to_array();
list($name, $value) = $array['Attribute']->first()->map(function($node, $i) {
return (string) $node;
});
http://docs.amazonwebservices.com/AWSSDKforPHP/latest/#i=CFSimpleXML
http://docs.amazonwebservices.com/AWSSDKforPHP/latest/#i=CFArray
enter code hereDo you mean something like this:
$data_tags = array();
foreach ( $select->body->GetAttributesResult AS $attr ) {
if ( $attr->Name == 'data_tags' ) {
$data_tags[] = $attr->Value;
}
}
Otherwise, I don't know what you want =)
edit
Are you sure GetAttributesResult is right? Don't you mean http://www.php.net/manual/en/simplexmlelement.attributes.php?
I would suggest something like that.
UPDATED:
function getAttributesIntoArray( $select )
{
$results = array();
$x = 0;
foreach ( $select->body->GetAttributesResult as $result )
{
foreach ( $result as $field )
{
if ( ! isset( $results[ $x ] ) )
{
$results[ $x ] = array();
}
// Assuming, that if the $field->Value is array, then it probably have only one element
if ( $field )
{
// or if ( isset( $results[ $x ][ (string) $field->Name ] ) ) instead of array_key_exists
if ( array_key_exists( (string) $field->Name, $results[ $x ] ) )
{
$results[ $x ][ (string) $field->Name ][] = ( is_array( $field->Value ) ) ? $field->Value[0] : $field->Value;
}
else
{
$results[ $x ][ (string) $field->Name ] = ( is_array( $field->Value ) ) ? $field->Value[0] : $field->Value;
}
}
}
$x++;
}
return $results;
}
I was able to get this one to work. Hope this helps.
protected function CFResponseToArray($response)
{
try {
if ($response->isOK()) {
$responseObj = $response->body->to_array()->getArrayCopy();
//log_message('info', print_r($responseObj, true));
$result = array();
if (isset($responseObj['SelectResult']['Item'])) {
if (is_array($responseObj['SelectResult']['Item'])) {
if (isset($responseObj['SelectResult']['Item']['Name'])) {
$itemObj = array();
//log_message('info', print_r($responseObj['SelectResult'], true));
$resultItem = $responseObj['SelectResult']['Item'];
$itemObj['Id'] = $resultItem['Name'];
$attributes = $resultItem['Attribute'];
for ($i = 0; $i < count($attributes); $i++) {
$itemObj[$attributes[$i]['Name']] = $attributes[$i]['Value'];
}
$result[] = $itemObj;
} else {
//log_message('info', print_r($responseObj['SelectResult'], true));
foreach ($responseObj['SelectResult']['Item'] as $resultItem) {
$itemObj = array();
$itemObj['Id'] = $resultItem['Name'];
$attributes = $resultItem['Attribute'];
for ($i = 0; $i < count($attributes); $i++) {
$itemObj[$attributes[$i]['Name']] = is_array($attributes[$i]['Value']) ? "" : $attributes[$i]['Value'];
}
$result[] = $itemObj;
}
if (isset($responseObj['SelectResult']['NextToken'])) {
$this->nextToken = $responseObj['SelectResult']['NextToken'];
} else {
$this->nextToken = '';
}
}
}
}
return $result;
}
} catch (exception $ex) {
log_message('error', $ex->getMessage());
}
}
function attrToArray($select) {
$results = array();
$x = 0;
foreach ( $select->body->GetAttributesResult as $result ) {
foreach ( $result as $field ) {
$check = (string) $field->Name;
if (isset($field) && array_key_exists($check, $results[$x] ) ) {
if ( ! is_array( $results[ $x ][$check] ) ) {
$val = (string) $results[ $x ][$check];
$results[ $x ][ $check ] = array();
$results[ $x ][ $check ][] = $val;
}
$results[ $x ][ $check ][] = (string) $field->Value;
} else {
$results[ $x ][ $check ] = (string) $field->Value;
}
}
$x++;
}
return $results;
}

Recursive PHP function that copies multidimensional array but replaces empty values

I have a multidimensional array that could be any size or depth. I'm basically trying replace empty values with a value but only in certain cases. Here is an example of the array, it's quite large but I want to illustrate my point well:
[field_ter] =>
[field_title] => Array
(
[0] => Array
(
[value] =>
)
)
[field_firstnames] => Array
(
[0] => Array
(
[value] => test9
)
)
[field_birth] => Array
(
[0] => Array
(
[value] =>
)
)
[field_postal] => Array
(
[0] => Array
(
[value] =>
)
)
[group_certificates] => Array
(
[0] => Array
(
[_delta] => 0
[field_cert_details] => Array
(
[value] =>
)
[field_cert_issuedate] => Array
(
[value] => Array
(
[date] =>
)
)
[field_cert_expiry] => Array
(
[value] => Array
(
[date] =>
)
)
[field_cert_issue_country] => Array
(
[value] =>
)
[field_cert_limits] => Array
(
[value] =>
)
)
[1] => Array
(
[_delta] => 1
[field_cert_details] => Array
(
[value] =>
)
[field_cert_issuedate] => Array
(
[value] => Array
(
[date] =>
)
)
[field_cert_expiry] => Array
(
[value] => Array
(
[date] =>
)
)
[field_cert_issue_country] => Array
(
[value] =>
)
[field_cert_limits] => Array
(
[value] =>
)
)
)
What I'm trying to do is find any element in the array that is empty, then replace the empty value with a value. I have an array of exceptions where the empty element is not replaced. This is the function I'm working on at the moment:
function check_empty(&$array) {
$exceptions = array('changed', 'form_build_id','date', 'status', 'op');
// This is the array we will return at the end of the function
$new_array = array();
foreach($array as $key => $value) {
if(is_array($value)) {
check_empty($value);
}
elseif ($value == '' && !in_array($key, $exceptions)) {
$new_array[$key] = '$$$';
}
else {
$new_array[$key] = $value;
}
}
return $new_array;
}
Could someone help me tweak my function or point me in the direction of a better way? I tried array_walk_recursive but it doesn't work with my arrays.
You need to assign the return value of the recursive check_empty:
function check_empty($array) {
$exceptions = array('changed', 'form_build_id','date', 'status', 'op');
// This is the array we will return at the end of the function
$new_array = array();
foreach ($array as $key => $value) {
if (is_array($value)) {
$new_array[$key] = check_empty($value);
}
elseif ($value == '' && !in_array($key, $exceptions)) {
$new_array[$key] = '$$$';
}
else {
$new_array[$key] = $value;
}
}
return $new_array;
}
if(is_array($value)) {
check_empty($value);
}
Here you don't return resulting value to anywhere. Probably that's the problem

Categories