I have the following code:-
if( $featured_query->have_posts() ): $property_increment = 0;
while( $featured_query->have_posts() ) : $featured_query->the_post();
$town = get_field('house_town');
$a = array($town);
$b = array_unique($a);
sort($b);
var_dump($b);
$property_increment++; endwhile; ?>
<?php endif; wp_reset_query();
var_dump(b) shows:-
array(1) { [0]=> string(10) "Nottingham" } array(1) { [0]=> string(9) "Leicester" } array(1) { [0]=> string(9) "Leicester" } array(1) { [0]=> string(11) "Mountsorrel" } array(1) { [0]=> string(12) "Loughborough" } array(1) { [0]=> string(12) "Loughborough" }
var_dump($town) shows:-
string(10) "Nottingham" string(9) "Leicester" string(9) "Leicester" string(11) "Mountsorrel" string(12) "Loughborough" string(12) "Loughborough"
var_dump($a) shows:-
array(1) { [0]=> string(10) "Nottingham" } array(1) { [0]=> string(9) "Leicester" } array(1) { [0]=> string(9) "Leicester" } array(1) { [0]=> string(11) "Mountsorrel" } array(1) { [0]=> string(12) "Loughborough" } array(1) { [0]=> string(12) "Loughborough" }
What I want to do is get the unique vales of $town and output them into a select option:-
<select>
<option value="Leicester">Leicester</option>';
<option value="Loughborough">Loughborough</option>';
<option value="Mountsorrel">Mountsorrel</option>';
</select>';
In alpha as above, any help would be much appreciated.
#collect all get_field('house_town') in while
$collect[] = get_field('house_town');
#then do the work
$html = implode('',
array_map(
function($a){
return "<option value='{$a}'>{$a}</option>";
},
array_unique($collect)
)
);
Your array needs to be un-nested with array_column before you sort it and make it unique. So after you initialised $a, continue like this:
$b = array_unique(array_column($a, 0));
sort($b);
and then make the HTML:
$html = "";
foreach($b as $town) {
$html .= "<option value='$town'>$town</option>";
}
echo "<select>$html</select>";
If you don't have array_column, then you can use this replacement:
function array_column($arr, $column) {
$res = array();
foreach ($arr as $el) {
$res[] = $el[$column];
}
return $res;
}
Here's a summary of Chris G's comment and trincot's code snippet for generating the HTML code.
Note: for testing purposes I have created the $town array manually here. Replace it by your statement $town = get_field('house_town');
<?php
$town = array(
"Nottingham",
"Leicester",
"Leicester",
"Mountsorrel",
"Loughborough",
"Loughborough"
);
// $town = get_field('house_town');
$html = "";
$town = array_unique($town);
sort($town);
foreach($town as $xtown) {
$html .= "<option value='$xtown'>$xtown</option>";
}
echo "<select>$html</select>";
?>
Basic/ General unique usage in while/ foreach loop
// refer to
$a = array($town); // $a in while/ foreach loop
if(current($a) != next($a)) {
// do your query here // get required unique here
}
// Note: caring and sharing
Related
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 ];
}, []);
I have this array:
array(5) {
[0]=>
array(4) {
["productCode"]=>
string(4) "X001"
["productUPC"]=>
string(3) "261"
["productTextSeq"]=>
string(1) "1"
["productTxtVal"]=>
string(5) "Text1"
}
[1]=>
array(4) {
["productCode"]=>
string(4) "X001"
["productUPC"]=>
string(3) "261"
["productTextSeq"]=>
string(1) "2"
["productTxtVal"]=>
string(5) "Text2"
}
[2]=>
array(4) {
["productCode"]=>
string(4) "X001"
["productUPC"]=>
string(3) "261"
["productTextSeq"]=>
string(1) "3"
["productTxtVal"]=>
string(5) "Text3"
}
[3]=>
array(4) {
["productCode"]=>
string(4) "X002"
["productUPC"]=>
string(3) "262"
["productTextSeq"]=>
string(1) "1"
["productTxtVal"]=>
string(5) "Text1"
}
[4]=>
array(4) {
["productCode"]=>
string(4) "X002"
["productUPC"]=>
string(3) "262"
["productTextSeq"]=>
string(1) "2"
["productTxtVal"]=>
string(5) "Text2"
}
}
With the above input, I want the output array to look like this:
array(2) {
[0]=>
array(3) {
["productCode"]=>
string(4) "X001"
["productUPC"]=>
string(3) "261"
["productTxtVal"]=>
string(17) "Text1 Text2 Text3"
}
[1]=>
array(3) {
["productCode"]=>
string(4) "X002"
["productUPC"]=>
string(3) "262"
["productTxtVal"]=>
string(11) "Text1 Text2"
}
}
The resulting array does not need the productTextSeq key, just the combined values of productTextVal, when the productCode is the same. I've searched SO for examples of this but it seems every example I've found are based on multiple input arrays. I know I can brute force this with nested foreach functions but would love a more elegant solution.
I ended up just doing it the brute force method, here is my solution if anyone's interested:
$productData = array();
$sortedData = array();
$comments = '';
$saveKey = '';
$appendComment = false;
$idx = 0;
foreach ($data as $key=>$value) {
foreach ($value as $k=>$v) {
if ($k == 'productCode') {
if ($v == $saveKey) {
$appendComment = true;
} else {
$appendComment = false;
$saveKey = $v;
if ($idx !== 0) { // Don't write to array on first iteration!
$productData['productTxtVal'] = $comments;
$sortedData[] = $productData;
}
}
}
if ($k == 'productTxtVal') {
if ($appendComment == true) {
$comments .= ' ' . trim($v);
} else {
$comments = trim($v);
}
}
}
$productData = $value;
$idx++;
}
Not "elegant" but it works. I also have a check after this logic in case only one productCode is in the original array, as it won't be written to the $sortedData array since the key never changes.
The following code assumes you control the contents of the original data array (due to risk of injection using extract() function) and that no 2 items with the same productCode have the same productTextSeq.
$products = [];
foreach ($data as $item) {
// extract contents of item array into variables
extract($item);
if (!isset($products[$productCode])) {
// create product array with code, upc, text as array
$products[$productCode] = compact('productCode', 'productUPC') + ['productTxtVal' => []];
}
// add text value to array with sequence as index
$products[$productCode]['productTxtVal'][$productTextSeq] = $productTxtVal;
}
$products = array_values( // ignore array keys
array_map(function($product) {
ksort($product['productTxtVal']); // sort text as array by index/ sequence
$product['productTxtVal'] = implode(' ', $product['productTxtVal']); // implode into string
return $product;
}, $products)
);
You can run the code here: https://repl.it/BWQL
I've created a super array which have 4 levels.
Here is the beast :
array(4) {
["arrayCoordinateur"]=>
array(2) {
["siret"]=>
array(1) {
[0]=>
string(14) "44306184100039"
}
["sigle"]=>
array(1) {
[0]=>
string(3) "NdP"
}
}
["arrayGroupMember"]=>
array(2) {
["siret"]=>
array(2) {
[0]=>
string(14) "44306184100039"
[1]=>
string(14) "44306184100039"
}
["sigle"]=>
array(2) {
[0]=>
string(7) "rerzrez"
[1]=>
string(5) "Autre"
}
}
["arrayPartEnt"]=>
array(2) {
["sigle"]=>
array(3) {
[0]=>
string(6) "Blabla"
[1]=>
string(11) "CharbonBleu"
[2]=>
string(3) "JsP"
}
["siret"]=>
array(3) {
[0]=>
string(14) "77408201000034"
[1]=>
string(14) "51133834500024"
[2]=>
string(14) "40794236600011"
}
}
["arrayPartenExt"]=>
array(2) {
["sigle"]=>
array(2) {
[0]=>
string(3) "BNN"
[1]=>
string(5) "13456"
}
["siret"]=>
array(1) {
[0]=>
string(14) "00000000000000"
}
}
}
as you can see, the structure is comped of 4 Array who have all subs array called "siret" and "sigle".
I would like to be able to loop only on those siret and sigle without being annoyed by the first level, to put them into a table.
Here is my table :
$i = 0;
foreach ($allPartenaires as $partenaire=>$data) {
for ($i=0; $i < count($data) ; $i++) {
echo "<tr>
<td>
".$data['sigle'][$i]."
</td>
<td>
".$data['siret'][$i]."
</td>
</tr>";
}
}
$allPartenaires being the super array at the beginning of this post.
This code doesn't work since all the subarray dont have the same size...
Any help would be greatly appreciated
I think this is what you need:
$data = array(
"arrayCoordinateur"=>array(
"siret"=>array(
"44306184100039",
),
"sigle"=>array(
"NdP",
),
),
"arrayGroupMember"=>array(
"siret"=>array(
"44306184100039",
"44306184100039",
),
"sigle"=>array(
"rerzrez",
"Autre",
),
),
"arrayPartEnt"=>array(
"siret"=>array(
"77408201000034",
"51133834500024",
"40794236600011",
),
"sigle"=>array(
"Blabla",
"CharbonBleu",
"JsP",
"Something",
),
),
);
echo '<table>';
foreach($data as $key => $value) {
$length = count($value['siret']) > count($value['sigle']) ? count($value['siret']) : count($value['sigle']);
for($i = 0; $i < $length; $i++) { //Now it works even if siret and single doesn't have same number of elemenets
$v1 = '-';
$v2 = '-';
if (isset($value['siret'][$i])) {
$v1 = $value['siret'][$i];
}
if (isset($value['sigle'][$i])) {
$v2 = $value['sigle'][$i];
}
echo
'
<tr>
<td>'.$v1.'</td>
<td>'.$v2.'</td>
</tr>
';
}
}
echo '</table>';
Result:
44306184100039 NdP
44306184100039 rerzrez
44306184100039 Autre
77408201000034 Blabla
51133834500024 CharbonBleu
40794236600011 JsP
- Something
nested foreach loops are what you need
foreach ($allPartenaires as $data) {
echo '<tr>';
foreach($data as $nestedArray) {
foreach($nestedArray as $content) {
echo "<td>{$content}</td>";
}
}
echo '</tr>';
}
I'm trying to get this array ($resdata) with object(SimpleXMLElement) into a php array:
$resdata =
array(59) {
[0]=> ...
[10]=> object(SimpleXMLElement)#294 (28) {
["reservation_id"]=> string(7) "8210614"
["event_id"]=> string(6) "279215"
["space_reservation"]=> array(2) {
[0]=> object(SimpleXMLElement)#344 (9) {
["space_id"]=> string(4) "3760"
["space_name"]=> string(9) "205"
["formal_name"]=> string(33) "Center" }
[1]=> object(SimpleXMLElement)#350 (9) {
["space_id"]=> string(4) "3769"
["space_name"]=> string(9) "207"
["formal_name"]=> string(32) "Right" } } }
}
I've tried:
$res = (array)$resdata;
$reservation = $res['reservation'];
$result = array();
foreach ($reservation as $key => $value){
$res = array($value);
$spid = $res[0]->space_reservation->space_id;
echo $value->event_id."<br />";
echo $spid."<br />";
}
This only outputs the first space_id and I need to get all the space_ids within "space_reservation" array. Not all records will have multiple space_ids. Any help pointing me in the right direction is appreciated. Not sure if I should use xpath but I need to re-write my foreach statement regardless.
I was hoping to be able to literally convert all references to "object(SimpleXMLElement)#_ (#)" to "array(#)"
[10]=> array (28) {
["reservation_id"]=> string(7) "8210614"
["event_id"]=> string(6) "279215"
["space_reservation"]=> array(2) {
[0]=> array (9) {
["space_id"]=> string(4) "3760"
["space_name"]=> string(9) "205"
["formal_name"]=> string(33) "Center" }
[1]=> array (9) {
["space_id"]=> string(4) "3769"
["space_name"]=> string(9) "207"
["formal_name"]=> string(32) "Right" } } }
}
the function in my cakephp 1.3 controller is this:
$xml = simplexml_load_string($string);
$this->data['events']= $xml->children();
$resdata = $this->data['events'];
$this->set('resdata',$resdata);
I think this should do what you are looking for:
foreach ($resdata as $res) {
echo $res->event_id . '<br />';
foreach ($res->space_reservation as $reservation) {
echo $reservation->space_id . '<br />';
}
}
Googled it and found a general solution for any SimpleXMLElement to array conversion:
function xml2array($xml) {
$arr = array();
foreach ($xml as $element) {
$tag = $element->getName();
$e = get_object_vars($element);
if (!empty($e)) {
$arr[$tag] = $element instanceof SimpleXMLElement ? xml2array($element) : $e;
}
else {
$arr[$tag] = trim($element);
}
}
return $arr;
}
I'm trying to add another column of data to each row in a foreach loop. It's purpose is to remember the element of data importeded from XML processed to an multidimensional array. It's stuck as a scalar though the var_dumps looks fine.
<?php
$KEY = 0;
foreach ($eventsArray as $keyMe){
$thisKey['KEY'][0] = strval($KEY);
$keyedArray = array_merge($keyMe, $thisKey);
$KEY++;
}
// Prep for multisort
foreach ($keyedArray as $key => $value){
$date[$key] = $value['DATE'];
$title[$key] = $value['TITLE'];
$link[$key] = $value['LINK'];
$slide[$key] = $value['SLIDE'];
$location[$key] = $value['LOCATION'];
$time[$key]= $value['TIME'];
$KEY[$key] = $value['KEY']; // Warning: Cannot use a scalar value as an array
}
/* var_dump(
array(7) {
["DATE"]=> array(1) { [0]=> string(10) "2012-12-18" }
["TITLE"]=> array(1) { [0]=> string(20) "Event Title" }
["LINK"]=> array(1) { [0]=> string(38) "aLinkLocation.htm" }
["SLIDE"]=> array(1) { [0]=> string(2) "16" }
["LOCATION"]=> array(1) { [0]=> string(8) "Location of Event" }
["TIME"]=> array(1) { [0]=> string(3) "8am" }
["KEY"]=> array(1) { [0]=> string(2) "23" }
}
*/