How to iterate through elements of an array up until its seventh - php

I have a function that iterates throughout an array
function ($data)
{
$path = $data->data->data->clicks;
foreach ($path as $key => $item){
if ($key >= 0) {
$array[] = $item->clicks;
}
}
return json_encode($array);
}
I try to make it iterate up until its seventh key, I have written an if statement but I am quite new to this and I don't know how to do this.
If it help the array structure look like this:
["data"]=>
object(stdClass)#212 (3) {
["status_code"]=>
int(200)
["data"]=>
object(stdClass)#211 (3) {
["days"]=>
int(30)
["total_clicks"]=>
int(6)
["clicks"]=>
array(30) {
[0]=>
object(stdClass)#215 (2) {
["clicks"]=>
int(0)
["day_start"]=>
int(1466395200)
}
[1]=>
object(stdClass)#216 (2) {
["clicks"]=>
int(0)
["day_start"]=>
int(1466308800)
}
[2]=>
object(stdClass)#217 (2) {
["clicks"]=>
int(0)
["day_start"]=>
int(1466222400)
}

Just add a variable that counts up and break when it's greater than 7
$num_loops = 0;
foreach ($path as $key => $item){
$num_loops++;
if($num_loops > 7) break;
if ($key >= 0) {
$array[] = $item->clicks;
}
}

The short way by using array_map and array_slice functions(no loops, no if conditions):
$path = $data->data->data->clicks;
$clicks = array_map(function($o){
return $o->clicks;
}, array_slice($path, 0, 7));

Related

how to use explode for an array of objects

I have an array like that:
array(5) {
["code"]=>
int(1)
["messageError"]=>
string(27) "La typologie est incorrecte"
["model"]=>
string(3) "lot"
["grp_regles"]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(3) {
["champ"]=>
string(21) "lot_surface_habitable"
["comparaison"]=>
string(7) "between"
["valeurAttendue"]=>
array(2) {
[0]=>
int(16)
[1]=>
int(40)
}
}
}
}
["prerequis"]=>
array(2) {
[0]=>
array(3) {
["champ"]=>
string(6) "typ_id"
["comparaison"]=>
string(1) "="
["valeurAttendue"]=>
int(1)
}
[1]=>
array(3) {
["champ"]=>
string(22) "tranche.fus.fup.fup_id"
["comparaison"]=>
string(1) "="
["valeurAttendue"]=>
int(1)
}
}
}
I want to do a foreach in "prerequis":
$modelRetrieve = $this->retrieveModel($model);
$modelFind = $modelRetrieve::find($id);
$arrayError=[];
$query = '';
$path = storage_path() . "/json/controle.json";
$json = file_get_contents($path);
foreach (json_decode($json,true) as $key => $value) {
$test = true;
var_dump($value);
if($value['model'] === $model ){
foreach ($value['prerequis'] as $key => $value2) {
if( $test && $modelFind[$value2['champ']] == (int)$value2["valeurAttendue"] )
{
$test = true;
}
}
}
}
I need in second foreach to use in $value2['champ'] where $value2['champ'] is "tranche.fus.fup_id. So I need to explode that to have ['tranche']['fus']['fup_id'].
How to use explode with that ?
thanks everyone :)
you can use laravel data_get helper:
data_get($value2, $value2['champ'])
To nest the $segments of the string starting with the innermost item of the result, we have to array_reverse() the $segments so we can loop over it and wrap each iteration's result with another array level in the next iteration until we looped through the whole $segments array.
$exploded = array_reduce(array_reverse(explode('.', $value2['champ'])), function($res, $segment) {
return [ $segment => $res ];
}, []);

notice trying to access array offset on value of type null wordpress plugins

i must update my website to the last version of php 7.4 after that i find this notice in some plugins
**> Notice: Trying to access array offset on value of type null in
C:\projets\htdocs\mapsport\wp-content\plugins\ekit-megamenu\library\scss\scss.inc.php
on line 1753**
protected function sortArgs($prototype, $args) {
$keyArgs = array();
$posArgs = array();
foreach ($args as $arg) {
list($key, $value) = $arg;
$key = $key[1]; // line 1753
if (empty($key)) {
$posArgs[] = $value;
} else {
$keyArgs[$key] = $value;
}
}
if (!isset($prototype)) return $posArgs;
$finalArgs = array();
foreach ($prototype as $i => $names) {
if (isset($posArgs[$i])) {
$finalArgs[] = $posArgs[$i];
continue;
}
$set = false;
foreach ((array)$names as $name) {
if (isset($keyArgs[$name])) {
$finalArgs[] = $keyArgs[$name];
$set = true;
break;
}
}
if (!$set) {
$finalArgs[] = null;
}
}
return $finalArgs;
}
how can i change the code without change my php version ?
the result after add var_dump($args); before the foreach Suggested by #Ro Achterberg
array(2) { [0]=> array(3) { [0]=> NULL [1]=> array(2) { [0]=>
string(3) "var" [1]=> string(23) "ekit-menu-simple__white" } [2]=>
bool(false) } [1]=> array(3) { [0]=> NULL [1]=> array(3) { [0]=>
string(6) "number" [1]=> string(3) "6.5" [2]=> string(1) "%" } [2]=>
bool(false) } }
On line 1752 the value of $key is NULL. It doesn't get any value. So can you please try $key = isset( $key[1] ) ? $key[1] : '';?

Remove/unset every other key in multidimensional array but preserve keys

I have a long multidimensional array with timestamps as keys which contain arrays of values. Something like this but with more timestamps:
array(3) {
[1502609400]=>
array(2) {
["Item1"]=>
array(1) {
["PRICE"]=>
float(100)
}
["Item2"]=>
array(1) {
["PRICE"]=>
float(50)
}
}
[1502611200]=>
array(2) {
["Item1"]=>
array(1) {
["PRICE"]=>
float(200)
}
["Item2"]=>
array(1) {
["PRICE"]=>
float(150)
}
}
[1502613000]=>
array(2) {
["Item1"]=>
array(1) {
["PRICE"]=>
float(500)
}
["Item2"]=>
array(1) {
["PRICE"]=>
float(250)
}
}
How can I remove every every second array of the array without losing the keys as timestamp? So I end up with this:
array(3) {
[1502609400]=>
array(2) {
["Item1"]=>
array(1) {
["PRICE"]=>
float(100)
}
["Item2"]=>
array(1) {
["PRICE"]=>
float(50)
}
}
[1502613000]=>
array(2) {
["Item1"]=>
array(1) {
["PRICE"]=>
float(500)
}
["Item2"]=>
array(1) {
["PRICE"]=>
float(250)
}
}
If I use a for loop and unset every second key I lose all the keys and end up with 0, 1, 2 etc. instead of the timestamp.
In a loop, check for index and unset every second element:
You can use custom $index variable, like this:
$index = 0; // points to first element
foreach ($array as $key => $value) {
if ($index % 2 != 0) { //check for un-even
unset($array[$key]);
}
$index++; // move pointer to next element
}
$i=1 // where the key to remove
$x=0; //loop to determine the key position
foreach ($array as $key=>$value){
if($x==$i){
unset($array[$key]);
}
$x++;
}
In that kind of case, a simple foreach can be more efficient perfwise than a standard function :
foreach ($array as $key => $val) {
if (array_key_exists('Item2', $val)) {
unset($val['Item2']);
}
}

Filter a multidemensional array

I have an array that looks kinda like this:
array(1) { ["Special"]=> array(4) { [0]=> array(2) { ["ID"]=> int(1) ["Visitors"]=> int(2) } [1]=> array(2) { ["ID"]=> int(4) ["Visitors"]=> int(5) } [2]=> array(2) { ["ID"]=> int(169) ["Visitors"]=> int(0) } } }
How can I filter it by 'ID' value, so the result would be looking like this (if I need to get arrays with ID = 4):
array(1) { ["Special"]=> array(4) { [1]=> array(2) { ["ID"]=> int(4) ["Visitors"]=> int(5) } } }
I tried to use that function, but it doesn't return what I need:
function search($array, $key, $value) {
$results = array();
if (is_array($array)) {
if (isset($array[$key]) && $array[$key] == $value) {
$results[] = $array;
}
foreach ($array as $subarray) {
$results = array_merge($results, search($subarray, $key, $value));
}
}
return $results; }
You can use array_filter to do this:
$result = array(
"Special" => array_filter($array["Special"], function($element) {
return $element["ID"] == 4;
})
);

Recursive traversal of object

I'm having trouble writing a recursive function to traverse this hierarchical structure
object(stdClass)#290 (6) {
["category_id"]=>
int(1)
["parent_id"]=>
int(0)
["name"]=>
string(4) "Root"
["position"]=>
int(0)
["level"]=>
int(0)
["children"]=>
array(2) {
[0]=>
object(stdClass)#571 (7) {
["category_id"]=>
int(2)
["parent_id"]=>
int(1)
["name"]=>
string(18) "Root MySite.com"
["is_active"]=>
int(0)
["position"]=>
int(0)
["level"]=>
int(1)
["children"]=>
array(11) {
[0]=>
object(stdClass)#570 (7) {
["category_id"]=>
int(15)
["parent_id"]=>
int(2)
["name"]=>
string(9) "Widgets"
["is_active"]=>
int(1)
["position"]=>
int(68)
["level"]=>
int(2)
["children"]=>
array(19) {
[0]=>
object(stdClass)#566 (7) {
["category_id"]=>
int(24)
["parent_id"]=>
int(15)
["name"]=>
string(16) "Blue widgets"
["is_active"]=>
int(1)
["position"]=>
int(68)
["level"]=>
int(3)
["children"]=>
array(0) {
}
}
<snip....>
As you can see this nested set can go on forever.. .
What I want to return is something like this
$categories("Root" => array("Root MySite.com" => array("Widgets" => array("Blue Widgets",...))))
[EDIT] : pasting my starting point for my recursive function that will simply "flatten out" an arry or object. I would think i could modify this to make get the data structure I'm looking for but haven't been able to get it quite right.
function array_flatten($array, $return)
{
// `foreach` can also iterate through object properties like this
foreach($array as $key => $value)
{
if(is_object($value))
{
// cast objects as an array
$value = (array) $value;
}
if(is_array($value))
{
$return = array_flatten($value,$return);
}
else
{
if($value)
{
$return[] = $value;
}
}
}
return $return;
}
The question is I can't quite figure out to build the structure I'm looking for recursively, or maybe there is a more elegant php way to do this?
Try this
function run($o) {
$return = array();
foreach ($o->children as $child) {
$return[$child->name] = run($child);
}
return empty($return) ? null : $return;
}
I don't have time to write a working answer, but here's some pseudo code to do it (half PHP, half JS)
This would create a flattened version of the tree by removing the children property of each element in your list.
$flattened = array();
function addElement(&$flattened, $list) {
for ($element in $list) {
$children = $element->children;
delete $element->children;
$flattened[] = $element;
if ($children) {
addElements($flattened, $children)
}
}
}
addElements($flattened, $treeHierarchy);
deep_order object or assoc_array
namespace a_nsp
class object_utils{
static function deep_order($IN, $desc = NULL) { // object or assoc_array
$O = new \stdClass;
$I = (array) $IN;
$keys = array_keys($I);
$desc ? rsort($keys) : asort($keys);
foreach ($keys as $k) {
$v = $I[$k];
//$v = json_decode($I[$k],1) ?: $I[$k]; // force conversion of json_string
if (is_array($v) || is_object($v)) {
$O->$k = self::deep_order($v, $desc);
}
else {
$O->$k=$v;
}
}
return $O; // object
}
}
use like
$ordered_obj = \a_nsp\object_utils::deep_order($orig_obj)

Categories