Splitting up a string - php - php

I have an array called $result, which is shown below:
array(1)
{ ["response"]=> array(3)
{ [0]=> array(1)
{ ["list"]=> array(2)
{ ["category"]=> string(6) "(noun)"
["synonyms"]=> string(27) "chelonian|chelonian reptile" }
}
[1]=> array(1)
{ ["list"]=> array(2)
{ ["category"]=> string(6) "(verb)"
["synonyms"]=> string(57) "capsize|turn turtle|overturn|turn over|tip over|tump over" }
}
[2]=> array(1)
{ ["list"]=> array(2)
{ ["category"]=> string(6) "(verb)"
["synonyms"]=> string(29) "hunt|run|hunt down|track down" }
}
}
}
I am trying to access the ["synonyms"] element, and split each word and store it in its own string, or perhaps an array of all the words. You can see the words are separated by the | symbol.
I have tried the following code, which did not work (results did not display, so explode did not work) :
$i=0;
foreach ($result["response"] as $value)
{
foreach ($value["list"]["synonyms"] as $temp)
{
$alternative[$i] = explode ("|", $temp);
$i++;
}
}
//OUTPUT THE RESULTS
$j=0;
foreach ($alternative as $echoalternative)
{
echo $j.": ".$echoalternative;
$j++;
}
Any ideas? Thanks guys.

You're trying to iterate over the string in your interior foreach. Try
foreach ($result["response"] as $value)
{
$alternative[$i] = explode ("|", $value["list"]["synonyms"]);
$i++;
}

To create an array of single dimensional arrays (given that you have three groups in your original array), you can do the following:
$out = array();
foreach ($arr['response'] as $key => $value){
$syns = explode('|', $value['list']['synonyms']);
foreach ($syns as $key2 => $value2){
$out[$key][] = $value2;
}
}
To access the single dimensional array for the group of synonyms with index 0, just do the following:
var_dump($out[0]);
Array(
[0] => chelonian
[1] => chelonian reptile
)
If you just want to display the synonyms, you can do something like this:
foreach ($arr['response'] as $key => $value){
$syns = explode('|', $value['list']['synonyms']);
foreach ($syns as $key2 => $value2){
echo $value2.', ';
}
echo "<br />";
}
Output:
chelonian, chelonian reptile,
capsize, turn turtle, overturn, turn over, tip over, tump over,
hunt, run, hunt down, track down,
However, if you want to include that in the original array, you can do this:
array_walk_recursive($arr, function (&$e, $k){
if (preg_match('#[\w\|]+#', $e)){
$e = explode('|', $e);
}
});
var_dump($arr);
Output:
Array(
[response] => Array
[0] => Array(
[list] => Array(
[category] => Array(
[0] => (noun)
)
[synonyms] => Array(
[0] => chelonian
[1] => chelonian reptile
)
)
)
[1] => Array(
[list] => Array(
[category] => Array(
[0] => (verb)
)
[synonyms] => Array(
[0] => capsize
[1] => turn turtle
[2] => overturn
[3] => turn over
[4] => tip over
[5] => tump over
)
)
)
[2] => Array(
[list] => Array(
[category] => Array(
[0] => (verb)
)
[synonyms] => Array(
[0] => hunt
[1] => run
[2] => hunt down
[3] => track down
)
)
)
)
)

The following refactored code should resolve the issue
$i=0;
foreach ($result["response"] as $value)
{
// print_r($value);
$temp = $value["list"]["synonyms"];
// echo $temp;
// foreach ($value["list"]["synonyms"] as $temp)
// {
$alternative[$i] = explode ("|", $temp);
$i++;
// }
}
//OUTPUT THE RESULTS
$j=0;
foreach ($alternative as $echoalternative)
{
print_r($echoalternative);
echo $j.": ".$echoalternative;
$j++;
}

Related

How to combine array with same element value

My array data :
$opt_val =
Array
(
[0] => Array
(
[0] => Array
(
[0] => 0|0|0|P3D
[1] => 0|0|1|P4D
[2] => 0|0|2|P5D
)
[1] => Array
(
[0] => 0|1|0|P3D
[1] => 0|1|1|P4D
[2] => 0|1|2|P5D
)
)
[1] => Array
(
[0] => Array
(
[0] => 1|0|0|P3D
[1] => 1|0|1|P4D
[2] => 1|0|2|P5D
)
[1] => Array
(
[0] => 1|1|0|P3D
[1] => 1|1|1|P4D
[2] => 1|1|2|P5D
)
)
)
I want to join above array with result :
Array
(
[0] => Array
(
[0] => 0|0|0|P3D#0|1|0|P3D (from Array[0][0][0]#Array[0][1][0])
[1] => 0|0|1|P4D#0|1|1|P4D
[2] => 0|0|2|P5D#0|1|2|P5D
)
[1] => Array
(
[0] => 1|0|0|P3D#1|1|0|P3D (from Array[1][0][0]#Array[1][1][0])
[1] => 1|0|1|P4D#1|1|1|P4D
[2] => 1|0|2|P5D#1|1|2|P5D
)
)
My code
for ($ov = 0; $ov < count($opt_val); $ov++) {
for ($ovi = 0; $ovi < count($opt_val[$ov]); $ovi++) {
for ($iv = 0; $iv < count($opt_val[$ov][$iv]); $iv++) {
$im_opt_val[$iv] = implode("#", $opt_val[$ov][$ovi]);
}
$impl_opt_val[$ov] = $im_opt_val;
}
}
Thank you
The following code snippet should do the trick.
<?php
declare(strict_types=1);
$opt_val = [
[
[
'0|0|0|P3D',
'0|0|1|P4D',
'0|0|2|P5D',
],
[
'0|1|0|P3D',
'0|1|1|P4D',
'0|1|2|P5D',
],
],
[
[
'1|0|0|P3D',
'1|0|1|P4D',
'1|0|2|P5D',
],
[
'1|1|0|P3D',
'1|1|1|P4D',
'1|1|2|P5D',
],
],
];
$result = [];
foreach ($opt_val as $outerArrayKey => $outerArray) {
foreach ($outerArray as $innerArray) {
foreach ($innerArray as $innerArrayKey => $innerArrayElement) {
if (!isset($result[$outerArrayKey][$innerArrayKey])) {
$result[$outerArrayKey][$innerArrayKey] = $innerArrayElement;
} else {
$result[$outerArrayKey][$innerArrayKey] .= '#'.$innerArrayElement;
}
}
}
}
var_dump($result);
The output would be:
array(2) {
[0]=>
array(3) {
[0]=>
string(19) "0|0|0|P3D#0|1|0|P3D"
[1]=>
string(19) "0|0|1|P4D#0|1|1|P4D"
[2]=>
string(19) "0|0|2|P5D#0|1|2|P5D"
}
[1]=>
array(3) {
[0]=>
string(19) "1|0|0|P3D#1|1|0|P3D"
[1]=>
string(19) "1|0|1|P4D#1|1|1|P4D"
[2]=>
string(19) "1|0|2|P5D#1|1|2|P5D"
}
}
I hope this work for you:
$finalFinalArray = [];
foreach($outerArray as $key => $innerArray){
$finalArray = [];
$inQueueArray = [];
foreach ($innerArray as $inInnerArray) {
$inQueueArray = array_merge($inQueueArray, $inInnerArray);
}
// Now, inner array is merged
for ($i = 0; $i < count($inQueueArray); $i++){
$finalArray[] = $inQueueArray[$i] + "#" + $inQueueArray[$i+3];
}
$finalFinalArray[] = $finalArray;
}
var_dump($finalFinalArray);
Didn't test it!

php multidimensional array group number of occurrences by type and date

I have the following array:
Array
(
[0] => Array
(
[0] => 2015-07-18
[1] => 22 SSH
)
[1] => Array
(
[0] => 2015-07-18
[1] => 80 HTTP
)
[2] => Array
(
[0] => 2015-07-18
[1] => 3389 Remote Desktop
)
[3] => Array
(
[0] => 2015-07-19
[1] => 3389 Remote Desktop
)
[4] => Array
(
[0] => 2015-07-19
[1] => 3389 Remote Desktop
)
)
and need the data counted by day and number of occurrences in the following format:
array(4) {
[0]=>
array(1) {
[0]=> "3389 Remote Desktop"
[1]=> "1,2"
}
[1]=>
array(1) {
[0]=> "22 SSH"
[1]=> "1,0"
}
[2]=>
array(1) {
[0]=> "80 HTTP"
[1]=> "1,0"
}
}
How can I achieve this? I am able to count all occurences but not grouped by date and type like this:
$counts = array();
foreach( $stack_stats_timeline as $value) {
foreach( $value as $k => $v) {
if( !isset( $counts[$k])) $counts[$k] = array();
if( !isset( $counts[$k][$v])) $counts[$k][$v] = 0;
$counts[$k][$v] += 1;
}
}
I think this'll help you to get it work
$result = array();
$count = 1;
foreach ($arr as $key => &$value) {
$hash = $value[1];
$result[$hash][0] = $value[1];
$result[$hash][1][$value[0]] = (isset($result[$hash][1][$value[0]])) ? $count + 1 : $count;
}
print_r(array_values($result));

Multidimensional array update

I am trying to update each language as a multidimensional array to another multidimensional array but it seems to be only saving the last key e.g.(lang_3) but not lang_1 & lang_2. Cracking my head to figure this out. Hope someone can point out my faults. ($country_specs = list of language, $get_code = country code)
$awards = array(
'award_year' => sanitize_array_text_field($_POST['award_year']),
'award_title_user' => sanitize_array_text_field($_POST['award_title_user']),
'award_description_user' => sanitize_array_text_field($_POST['award_description_user'])
);
foreach ($country_specs as $specs => $value) {
if ($value[0] == $get_code ) {
foreach ($value['lang'] as $lang_key => $lang) {
$awards_title = 'award_title_'.$lang_key;
$awards_description = 'award_description_'.$lang_key;
$awards_lang = array(
$awards_title => sanitize_array_text_field($_POST[$awards_title]),
$awards_description => sanitize_array_text_field($_POST[$awards_description])
);
update_user_meta($user_id, 'awards', array_merge($awards,$awards_lang));
}
}
}
Current code output example:
Array (
[award_year] => Array (
[0] => 1999-01
[1] => 2010-02 )
[award_title_user] => Array (
[0] => 2
[1] => tt )
[award_description_user] => Array (
[0] => 2
[1] => ddd )
[award_title_lang3] => Array (
[0] => 2CC
[1] => zz )
[award_description_lang3] => Array (
[0] => 2CCCCCCC
[1] => dzz ) )
Working code as follows.
$awards = array(
'award_year' => sanitize_array_text_field($_POST['award_year']),
'award_title_user' => sanitize_array_text_field($_POST['award_title_user']),
'award_description_user' => sanitize_array_text_field($_POST['award_description_user'])
);
$awards_new_lang = array();
foreach ($country_specs as $specs => $value) {
if ($value[0] == $get_code ) {
foreach ($value['lang'] as $lang_key => $lang) {
$awards_title = 'award_title_'.$lang_key;
$awards_description = 'award_description_'.$lang_key;
$awards_new_lang[$awards_title] = sanitize_array_text_field($_POST[$awards_title]);
$awards_new_lang[$awards_description] = sanitize_array_text_field($_POST[$awards_description]);
}
}
}
$array_merge_new = array_merge($awards, $awards_new_lang);
update_user_meta($user_id, 'awards', $array_merge_new);
I created a new array ($awards_new_lang) and did an array merge with the old array, thus combining both of the arrays together.
Try this code, it outputs as expected, I tried the mimic the variables structures
<?php
$awards = array(
'award_year' => '1999',
'award_title_user' => '2',
'award_description_user' => '2CCCCCCC'
);
$value = array();
$value['lang'] = array(1, 2, 3);
foreach ($value['lang'] as $lang_key) {
$awards_title = 'award_title_'.$lang_key;
$awards_description = 'award_description_'.$lang_key;
$awards_lang = array(
$awards_title => "$lang_key title",
$awards_description => "$lang_key desc"
);
//array merge returns an array, we save the changes here to use them later when the loops are through
$awards = array_merge($awards,$awards_lang);
}
echo '<pre>';
//Final updated version of the array
var_dump($awards);
echo '</pre>';
?>
Outputs:
array(9) {
["award_year"]=>
string(4) "1999"
["award_title_user"]=>
string(1) "2"
["award_description_user"]=>
string(8) "2CCCCCCC"
["award_title_1"]=>
string(7) "1 title"
["award_description_1"]=>
string(6) "1 desc"
["award_title_2"]=>
string(7) "2 title"
["award_description_2"]=>
string(6) "2 desc"
["award_title_3"]=>
string(7) "3 title"
["award_description_3"]=>
string(6) "3 desc"
}

How to get rid of duplicate values from multidimensional array

I want to remove duplicate values from multi-dim array, I tried all the possible solutions which is already described but for me, is not working, can anyone please correct it?
Here's my Array:
Array (
[0] => Array (
[0] => element_10
[1] => block_1
[2] => element_4
[3] => element_1
[4] => element_3
)
[1] => Array (
[0] => block_1
[1] => block_2
[2] => element_8
[3] => element_10
[4] => element_12
[5] => element_14
[6] => element_4
[7] => element_2
[8] => element_3
[9] => element_9
[10] => element_13
[11] => element_7
)
)
Where I want the array in this format:
Array (
[0] => Array (
[0] => element_10
[1] => block_1
[2] => element_4
[3] => element_1
[4] => element_3
)
[1] => Array (
[1] => block_2
[2] => element_8
[4] => element_12
[5] => element_14
[7] => element_2
[9] => element_9
[10] => element_13
[11] => element_7
)
)
Ican setup the key indexes later.
I tried:
function multi_unique($array) {
foreach ($array as $k=>$na)
$new[$k] = serialize($na);
$uniq = array_unique($new);
foreach($uniq as $k=>$ser)
$new1[$k] = unserialize($ser);
return ($new1);
}
No Luck, then I tried:
function array_unique_multidimensional($input)
{
$serialized = array_map('serialize', $input);
$unique = array_unique($serialized);
return array_intersect_key($input, $unique);
}
Still same array returning.
I tried this method too:
function super_unique($array)
{
$result = array_map("unserialize", array_unique(array_map("serialize", $array)));
foreach ($result as $key => $value)
{
if ( is_array($value) )
{
$result[$key] = self::super_unique($value);
}
}
return $result;
}
Please help me, I know it's pretty simple I don't know where I'm losing?
Thanks,
You need to iterate over your list of input arrays. For each value in that array, you need to see if you've previously encountered it, so you'll have to keep a super-set of all values across all arrays, which you gradually append to. If a value already exists in the super-set array, you can remove it, otherwise you can append it.
function multi_unique($arrays) {
$all_values = array();
foreach ($arrays as &$array) {
foreach ($array as $index => $value) {
if (in_array($value, $all_values)) {
// We've seen this value previously
unset($array[$index]);
} else {
// First time we've seen this value, let it pass but record it
$all_values[] = $value;
}
}
}
return $arrays;
}
$values = array (
array ( 'element_10', 'block_1', 'element_4', 'element_1', 'element_3',) ,
array ( 'block_1', 'block_2', 'element_8', 'element_10', 'element_12', 'element_14', 'element_4', 'element_2', 'element_3', 'element_9', 'element_13', 'element_7',)
);
var_dump(multi_unique($values));
Output:
array(2) {
[0]=>
array(5) {
[0]=>
string(10) "element_10"
[1]=>
string(7) "block_1"
[2]=>
string(9) "element_4"
[3]=>
string(9) "element_1"
[4]=>
string(9) "element_3"
}
[1]=>
array(8) {
[1]=>
string(7) "block_2"
[2]=>
string(9) "element_8"
[4]=>
string(10) "element_12"
[5]=>
string(10) "element_14"
[7]=>
string(9) "element_2"
[9]=>
string(9) "element_9"
[10]=>
string(10) "element_13"
[11]=>
string(9) "element_7"
}
}
If you just want to remove duplicates from the second entry of your array, use array_diff():
$array[1] = array_diff($array[1], $array[0]);
Iterate if you want to apply it to an arbitrary length.
Why are you using the serialize function.
Use array_diff instead.
A simple would be.
$orginal = array(array(values), array(values), ...);
$copy = $original;
foreach($original as $k => $subArray) {
$tmpCopy = $copy;
unset($tmpCopy[$k]);
unshift($tmpCopy, $subArray);
$tmpCopy = array_values($tmpCopy);
$original[$k] = call_user_func_array('array_diff', $tmpCopy);
}
This works for a two dimensions array.
Hope it helps.

PHP recursive array from JSON to key-value to values

I want to apologize in advanced if this was already asked, I'm not exactly sure what this would be called.
I'm storing data from a form into a MongoDB database and I'd like to create defined key-value pairs to make sorting easier.
Using this code I am able to do this with a one-dimensional array, but it does not work with multidimensional arrays:
/* $array = The array */
$new_array = array();
foreach ($array as $key => $value) {
array_push($new_array, array(
'name' => $key,
'value' => $value
));
}
Example:
Input array:
Array
(
[email] => test#mail.com
[name] => John
[sports] => Array
(
[outdoor] => Array
(
[0] => Football
[1] => Baseball
)
[indoor] => Array
(
[0] => Basketball
[1] => Hockey
)
)
)
Output array:
Array
(
[0] => Array
(
[name] => email
[value] => test#mail.com
)
[1] => Array
(
[name] => name
[value] => John
)
[2] => Array
(
[name] => sports
[value] => Array
(
[outdoor] => Array
(
[0] => Football
[1] => Baseball
)
[indoor] => Array
(
[0] => Basketball
[1] => Hockey
)
)
)
)
Notice how it stops at the sports value array and does not change the array within it. How can I continue this pattern throughout all the arrays within it?
You can use recursion:
function keyValue($array){
$new_array = array();
foreach ($array as $key => $value) {
array_push($new_array, array(
'name' => $key,
'value' => is_array($value) ? keyValue($value) : $value
));
}
return $new_array;
}
Try this on for size:
$array = array(
'email' => 'test#email.com',
'name' => 'John',
'sport' => array('Soccor', 'Hockey')
);
$func = function($value, $key) {
$return = array();
$return['name'] = $key;
$return['value'] = $value;
return $return;
};
$parsed = array_map($func, $array, array_keys($array));
For me, this returned:
array(3) {
[0]=>
array(2) {
["name"]=>
string(5) "email"
["value"]=>
string(14) "test#email.com"
}
[1]=>
array(2) {
["name"]=>
string(4) "name"
["value"]=>
string(4) "John"
}
[2]=>
array(2) {
["name"]=>
string(5) "sport"
["value"]=>
array(2) {
["outdoor"]=>
array(2) {
[0]=>
string(8) "Football"
[1]=>
string(8) "Baseball"
}
["indoor"]=>
array(2) {
[0]=>
string(10) "Basketball"
[1]=>
string(6) "Hockey"
}
}
}
}
It is pretty simple to turn associative arrays to JSON objects (StdClass) and vice versa, preserving native data types (int, float, bool). Here's my attempt:
To Key-Value Array
function toKeyValue($values)
{
$result = [];
foreach ($values as $key => $value)
{
if (is_array($value)) {
$result[$key] = toKeyValue($value);
} elseif (is_object($value)) {
$result[$key] = toKeyValue((array) $value);
} else {
$result[$key] = $value;
}
}
return $result;
}
To JSON Object
function toJson($values)
{
return json_decode(json_encode($values));
}
$values should always be an array.

Categories