I have the following array stored in the wordpress options table and I need to get the value of each title
a:1:{s:14:"swd_line_items";a:3:{i:0;a:1:{s:5:"title";s:9:"asdfasdfa";}i:1;a:1:{s:5:"title";s:13:"asdf asdf ada";}i:2;a:1:{s:5:"title";s:29:"fffffffffffffffffffffffffffff";}}}
I've tried nested foreach loops but nothing I do seems to work. There must be a simple solution?
function swd_get_line_items() {
$line_items = get_option('line_items_array');
$items = array();
foreach( $line_items as $item => $value ) {
foreach ($value as $new => $v) {
$items[] = array(
$new => $v
);
}
}
return $line_items;
}
Hope this helps :)
$array = unserialize('a:1:{s:14:"swd_line_items";a:3:{i:0;a:1:{s:5:"title";s:9:"asdfasdfa";}i:1;a:1:{s:5:"title";s:13:"asdf asdf ada";}i:2;a:1:{s:5:"title";s:29:"fffffffffffffffffffffffffffff";}}}');
foreach($array['swd_line_items'] as $item) {
echo $item['title'];
}
get_option() perfectly unsezrializes an array so there is no need to do it as the two other answers suggested it.
Then what you have is a two dimensional array but you are perfectly browsing it with two nested foreach.
By the way here is the final output of your code:
As you can see you perfectly extracted the titles:
Array
(
[0] => Array
(
[0] => Array
(
[title] => asdfasdfa
)
)
[1] => Array
(
[1] => Array
(
[title] => asdf asdf ada
)
)
[2] => Array
(
[2] => Array
(
[title] => fffffffffffffffffffffffffffff
)
)
)
But the issue here is that you do not return this array but you return this one:
return $line_items;
Change it into
return $items;
you mean this ?
function swd_get_line_items($serialized_array)
{
$line_items = unserialize($serialized_array);
$items = array();
foreach ($line_items['swd_line_items'] as $key => $item)
{
$items[$key] = $item['title'];
}
return $items;
}
Related
In a foreach loop i would like to compare [name] value beetween different arrays but they have not the same levels.
Array(
[array1] => Array
(
[0] => WP_Term Object
(
[name] => Plafond
)
)
[array2] => WP_Term Object
(
[name] => Chaudière
)
[array3] => Array
(
[0] => WP_Term Object
(
[name] => Pla
)
[1] => WP_Term Object
(
[name] => Toc
)
)
)
I don't know how could i get the [name] in the same loop whereas levels are different.
I have tried to make :
foreach( $fields as $name => $value )
{
echo $value->name; }
Should i add another loop in the first loop ?
thanks
So your data looks like this:
$json = '{"array1":[{"name":"Plafond"}],"array2":{"name":"Chaudière"},"array3":[{"name":"Pla"},{"name":"Toc"}]}';
$array = json_decode($json);
If you don't know how deep it will go, a simple recursive function should work. Perhaps something like this:
function get_name($o, &$output) {
if (is_array($o)) {
foreach($o as $v) {
get_name($v, $output);
}
} elseif (property_exists($o, "name")) {
$output[] = $o->name;
}
}
$output = [];
foreach ($array as $v) {
get_name($v, $output);
}
If you data is going to look like the sample you provided (i.e. it will always be first or second level) then you don't need to worry about recursion.
$output = [];
foreach ($array as $k=>$v) {
if (is_array($v)) {
foreach ($v as $k2=>$v2) {
$output[] = $v2->name;
}
} else {
$output[] = $v->name;
}
}
Either way, your output values are all in the $output array:
print_r($output);
Output:
Array
(
[0] => Plafond
[1] => Chaudière
[2] => Pla
[3] => Toc
)
You can use array_map, array_key_exists to retrive the name index from the array
$jsonFormat = '{"array1":[{"name":"Plafond"}],"array2":{"name":"Chaudière"},"array3":[{"name":"Pla"},{"name":"Toc"}]}';
$jsonArray = json_decode($jsonFormat,true);
$res = [];
array_map(function($v) use (&$res){
if(array_key_exists('name', $v)){
$res[] = $v['name'];
}else{
foreach($v as $_key => $_value){
$res[] = $_value['name'];
}
}
}, $jsonArray);
echo '<pre>';
print_r($res);
Result:-
Array
(
[0] => Plafond
[1] => Chaudière
[2] => Pla
[3] => Toc
)
You can use $res to compare the names.
Array
(
[data] => Array
(
[0] => Array
(
['degree_level'] => Bachelor's
)
[1] => Array
(
['field_of_study'] => Science
)
[2] => Array
(
['grade_point'] => 3
)
[3] => Array
(
['criteria'] => desired
)
)
)
What I want :
Array
(
[data] => Array
(
['degree_level'] => Bachelor's
['field_of_study'] => Science
['grade_point'] => 3
['criteria'] => desired
)
)
You should use array_flatten(); to achieve your goal like this,
$flattened = array_flatten(Your_Data_Array);
Please give it a try and let me know.
UPDATE
$flattened = array_map(function($item) {
return $item[0];
}, Your_Data_Array);
For more information you can visit this for PHP functions.
Let me know in case of any queries.
$output = array_map(function($item) { return $item[0]; }, $myArray);
Try this,
foreach($data as $key1=>$val1){
foreach($val1 as $key2=>$val2){
$new_array[$key2] = $val2;
}
}
You can do it by loop.
foreach ($data as $key => $value) {
foreach ($value as $key1 => $value2) {
$data[$key1] = $value2;
}
}
You could use for example a double foreach loop to use the key and the value from the second loop and add those to the $arrays["data"] array.
Then you could use unset to remove the nested arrays.
$arrays = [
"data" => [
["degree_level" => " Bachelor's"],
["field_of_study" => "Science"],
["grade_point" => 3],
["criteria" => "desired"]
]
];
foreach($arrays["data"] as $dataKey => $data) {
foreach ($data as $key => $value) {
$arrays["data"][$key] = $value;
}
unset($arrays["data"][$dataKey]);
}
print_r($arrays);
That would give you:
Array
(
[data] => Array
(
[degree_level] => Bachelor's
[field_of_study] => Science
[grade_point] => 3
[criteria] => desired
)
)
Demo
you can achieve this using array_collapse.
Link
EDIT :
while tag has changed.
Here is the core php solution based on Laravel array_collapse:
function collapse($array)
{
$results = [];
foreach ($array as $values) {
if (! is_array($values)) {
continue;
}
$results = array_merge($results, $values);
}
return $results;
}
I am struggling with an array that I need to convert into a new array based on the unique array keys. My current result looks like below. Each array represent just a part of the desired result (pivot) where I need a [menu_name], [menu_url] and [menu_target] as result and when the next array begins with the same keys, etc. So the way I see it to achieve this is to construct a new array, each time an array_key_exist in the array. But i am unable to achieve this.
Array
(
Array
(
[menu_name] => Contact
)
Array
(
[menu_url] => /contact
)
Array
(
[menu_target] => _blank
)
Array
(
[menu_name] => Home
)
Array
(
[menu_url] => /home
)
Array
(
[menu_target] => _self
)
)
The desired array I want to create looks like this:
Array
(
[0] => Array
(
[menu_name] => Contact,
[menu_url] => /contact,
[menu_target] => _blank
)
[1] => Array
(
[menu_name] => Home,
[menu_url] => /home,
[menu_target] => _blank
)
)
Here is my code so far (incomplete):
$result = array();
foreach($array as $option => $value)
{
$result[$value->option_key] = $value->option_value;
$new_array = array();
if(array_key_exist($value->option_key, $new_array))
{
// here is where I get stuck….
print_r($new_array);
}
}
I hope some one can get me in the right direction to further complete the code with the desired result.
You can use a var you increment each time key already exists :
$result = array();
$i = 0;
foreach($array as $option => $value)
{
if ( array_key_exists($value->option_key, $result[$i]) ) $i++;
$result[$i][$value->option_key] = $value->option_value;
}
Another way, is if the current batch of keys are complete, go to the next one and fill up the next one. Example:
$values = array(array('menu_name' => 'Contact'),array('menu_url' => '/contact'),array('menu_target' => '_blank'),array('menu_name' => 'Home'),array('menu_url' => '/home'),array('menu_target' => '_self'),);
$new_values = array();
$x = 0;
$columns = array_unique(array_map(function($var){
return key($var);
}, $values));
foreach($values as $value) {
$current_key = key($value);
$new_values[$x][$current_key] = reset($value);
if(array_keys($new_values[$x]) == $columns) $x++;
}
echo '<pre>';
print_r($new_values);
Sample Demo
Provided your answer is always grouped by threes, as posted in your example.
This is an alternative method to djidi's answer incase you wanted to see it done with silly loops.
$new = array_chunk($a, 3);
$d = array();
foreach($new as $i => $group) {
foreach($group as $index => $item) {
foreach($item as $name=>$val) {
$d[$i][$name] = $val;
}
}
}
Which returns:
Array
(
[0] => Array
(
[menu_name] => Contact
[menu_url] => /contact
[menu_target] => _blank
)
[1] => Array
(
[menu_name] => Home
[menu_url] => /home
[menu_target] => _self
)
)
Example Demo
I have two multidimensional arrays. First one $properties contains english names and their values. My second array contains the translations. An example
$properties[] = array(array("Floor"=>"5qm"));
$properties[] = array(array("Height"=>"10m"));
$translations[] = array(array("Floor"=>"Boden"));
$translations[] = array(array("Height"=>"Höhe"));
(They are multidimensional because the contains more elements, but they shouldn't matter now)
Now I want to translate this Array, so that I its at the end like this:
$properties[] = array(array("Boden"=>"5qm"));
$properties[] = array(array("Höhe"=>"10m"));
I have managed to build the foreach construct to loop through these arrays, but at the end it is not translated, the problem is, how I tell the array to replace the key with the value.
What I have done is this:
//Translate Array
foreach ($properties as $PropertyArray) {
//need second foreach because multidimensional array
foreach ($PropertyArray as $P_KiviPropertyNameKey => $P_PropertyValue) {
foreach ($translations as $TranslationArray) {
//same as above
foreach ($TranslationArray as $T_KiviTranslationPropertyKey => $T_KiviTranslationValue) {
if ($P_KiviPropertyNameKey == $T_KiviTranslationPropertyKey) {
//Name found, save new array key
$P_KiviPropertyNameKey = $T_KiviTranslationValue;
}
}
}
}
}
The problem is with the line where to save the new key:
$P_KiviPropertyNameKey = $T_KiviTranslationValue;
I know this part is executed correctly and contains the correct variables, but I believe this is the false way to assing the new key.
This is the way it should be done:
$properties[$oldkey] = $translations[$newkey];
So I tried this one:
$PropertyArray[$P_KiviPropertyNameKey] = $TranslationArray[$T_KiviTranslationPropertyKey];
As far as I understood, the above line should change the P_KiviPropertyNameKey of the PropertyArray into the value of Translation Array but I do not receive any error nor is the name translated. How should this be done correctly?
Thank you for any help!
Additional info
This is a live example of the properties array
Array
(
[0] => Array
(
[country_id] => 4402
)
[1] => Array
(
[iv_person_phone] => 03-11
)
[2] => Array
(
[companyperson_lastname] => Kallio
)
[3] => Array
(
[rc_lot_area_m2] => 2412.7
)
[56] => Array
(
[floors] => 3
)
[57] => Array
(
[total_area_m2] => 97.0
)
[58] => Array
(
[igglo_silentsale_realty_flag] => false
)
[59] => Array
(
[possession_partition_flag] => false
)
[60] => Array
(
[charges_parkingspace] => 10
)
[61] => Array
(
[0] => Array
(
[image_realtyimagetype_id] => yleiskuva
)
[1] => Array
(
[image_itemimagetype_name] => kivirealty-original
)
[2] => Array
(
[image_desc] => makuuhuone
)
)
)
And this is a live example of the translations array
Array
(
[0] => Array
(
[addr_region_area_id] => Maakunta
[group] => Kohde
)
[1] => Array
(
[addr_town_area] => Kunta
[group] => Kohde
)
[2] => Array
(
[arable_no_flag] => Ei peltoa
[group] => Kohde
)
[3] => Array
(
[arableland] => Pellon kuvaus
[group] => Kohde
)
)
I can build the translations array in another way. I did this like this, because in the second step I have to check, which group the keys belong to...
Try this :
$properties = array();
$translations = array();
$properties[] = array("Floor"=>"5qm");
$properties[] = array("Height"=>"10m");
$translations[] = array("Floor"=>"Boden");
$translations[] = array("Height"=>"Höhe");
$temp = call_user_func_array('array_merge_recursive', $translations);
$result = array();
foreach($properties as $key=>$val){
foreach($val as $k=>$v){
$result[$key][$temp[$k]] = $v;
}
}
echo "<pre>";
print_r($result);
output:
Array
(
[0] => Array
(
[Boden] => 5qm
)
[1] => Array
(
[Höhe] => 10m
)
)
Please note : I changed the array to $properties[] = array("Floor"=>"5qm");, Removed a level of array, I guess this is how you need to structure your array.
According to the structure of $properties and $translations, you somehow know how these are connected. It's a bit vague how the indices of the array match eachother, meaning the values in $properties at index 0 is the equivalent for the translation in $translations at index 0.
I'm just wondering why the $translations array need to have the same structure (in nesting) as the $properties array. To my opinion the word Height can only mean Höhe in German. Representing it as an array would suggest there are multiple translations possible.
So if you could narrow down the $translations array to an one dimensional array as in:
$translation = array(
"Height"=>"Höhe",
"Floor"=>"Boden"
);
A possible loop would be
$result = array();
foreach($properties as $i => $array2) {
foreach($array2 as $i2 => $array3) {
foreach($array3 as $key => $value) {
$translatedKey = array_key_exists($key, $translations) ?
$translations[$key]:
$key;
$result[$i][$i2][$translatedKey] = $value;
}
}
}
(I see every body posting 2 loops, it's an array,array,array structure, not array,array ..)
If you cannot narrow down the translation array to a one dimensional array, then I'm just wondering if each index in the $properties array matches the same index in the $translations array, if so it's the same trick by adding the indices (location):
$translatedKey = $translations[$i][$i2][$key];
I've used array_key_exists because I'm not sure a translation key is always present. You have to create the logic for each case scenario yourself on what to check or not.
This is a fully recursive way to do it.
/* input */
$properties[] = array(array("Floor"=>"5qm", array("Test"=>"123")));
$properties[] = array(array("Height"=>"10m"));
$translations[] = array(array("Floor"=>"Boden", array("Test"=>"Foo")));
$translations[] = array(array("Height"=>"Höhe"));
function array_flip_recursive($arr) {
foreach ($arr as $key => $val) {
if (is_array($val)) {
$arr[$key] = array_flip_recursive($val);
}
else {
$arr = #array_flip($arr);
}
}
return $arr;
}
function array_merge_it($arr) {
foreach ($arr as $key => $val) {
if (is_array($val)) {
$arr[$key] = array_merge_it($val);
} else {
if(isset($arr[$key]) && !empty($arr[$key])) {
#$arr[$key] = $arr[$val];
}
}
}
return $arr;
}
function array_delete_empty($arr) {
foreach ($arr as $key => $val) {
if (is_array($val)) {
$arr[$key] = array_delete_empty($val);
}
else {
if(empty($arr[$key])) {
unset($arr[$key]);
}
}
}
return $arr;
}
$arr = array_replace_recursive($properties, $translations);
$arr = array_flip_recursive($arr);
$arr = array_replace_recursive($arr, $properties);
$arr = array_merge_it($arr);
$arr = array_delete_empty($arr);
print_r($arr);
http://sandbox.onlinephpfunctions.com/code/d2f92605b609b9739964ece9a4d8f389be4a7b81
You have to do the for loop in this way. If i understood you right (i.e) in associative array first key is same (some index).
foreach($properties as $key => $values) {
foreach($values as $key1 => $value1) {
$propertyResult[] = array($translations[$key][$key1][$value1] => $properties[$key][$key1][$value1]);
}
}
print_r($propertyResult);
I have an 2d array which returns me this values:
Array (
[0] => Array (
[0] => wallet,pen
[1] => perfume,pen
)
[1] => Array (
[0] => perfume, charger
[1] => pen,book
).
Out of this i would like to know if it is possible to create a function which would combine the array going this way,and create a new one :
if for example [0] => Array ( [0] => wallet,pen [1] => perfume,pen ) then should be equal to
[0] => Array ( [0] => wallet,pen, perfume ) because there is a common word else do nothing.
And also after that retrieve each words as strings for further operations.
How can i make the values of such an array unique. Array ( [0] => Array ( [0] => wallet [1] => pen [2] => perfume [3] => pen) ) as there is pen twice i would like it to be deleted in this way ( [0] => Array ( [0] => wallet [1] => pen [2] => perfume) )
It's just a matter of mapping the array and combining the inner arrays:
$x = [['wallet,pen', 'perfume,pen'], ['perfume,charger', 'pen,book']];
$r = array_map(function($item) {
return array_unique(call_user_func_array('array_merge', array_map(function($subitem) {
return explode(',', $subitem);
}, $item)));
}, $x);
Demo
This first splits all the strings based on comma. They are then merged together with array_merge() and the duplicates are removed using array_unique().
See also: call_user_func_array(), array_map()
Try this :
$array = Array (Array ( "wallet,pen", "perfume,pen" ), Array ( "perfume, charger", "pen,book" ));
$res = array();
foreach($array as $key=>$val){
$temp = array();
foreach($val as $k=>$v){
foreach(explode(",",$v) as $vl){
$temp[] = $vl;
}
}
if(count(array_unique($temp)) < count($temp)){
$res[$key] = implode(",",array_unique($temp));
}
else{
$res[$key] = $val;
}
}
echo "<pre>";
print_r($res);
output :
Array
(
[0] => wallet,pen,perfume
[1] => Array
(
[0] => perfume, charger
[1] => pen,book
)
)
You can eliminate duplicate values while pushing them into your result array by assigning the tag as the key to the element -- PHP will not allow duplicate keys on the same level of an array, so any re-encountered tags will simply be overwritten.
You can use recursion or statically written loops for this task.
Code: (Demo)
$result = [];
foreach ($array as $row) {
foreach ($row as $tags) {
foreach (explode(',', $tags) as $tag) {
$result[$tag] = $tag;
}
}
}
var_export(array_values($result));
Code: (Demo)
$result = [];
array_walk_recursive(
$array,
function($v) use(&$result) {
foreach (explode(',', $v) as $tag) {
$result[$tag] = $tag;
}
}
);
var_export(array_values($result));