Basic Array Referencing Php - php

How can I reference the following dynamic arrays' elements ?
$log = array();
$arr1 = array ('a'=>'6:16pm','b'=>2,'c'=>3,'d'=>4,'e'=>5);
$arr2 = array ('a'=>'6:24pm','b'=>20,'c'=>30,'d'=>40,'e'=>50);
$log = array_merge($log, array($arr1['a']=>$arr1));
$log = array_merge($log, array($arr2['a']=>$arr2)); //<-- to use time as key
print_r($log);
for ($x = 0; $x < count($log); $x++) {
print_r ($log[0][$x]['a']); // <-- referencing issue Undefined offset: 0 .. line 20
}
//------ produces
Array
(
[6:16pm] => Array
(
[a] => 6:16pm
[b] => 2
[c] => 3
[d] => 4
[e] => 5
)
[6:24pm] => Array
(
[a] => 6:24pm
[b] => 20
[c] => 30
[d] => 40
[e] => 50
)
)
I'm pretty sure it has something to do with the way I'm naming the $log main array.. and there's probably a better way to do what I wish(.. add/ new elements to $log using the time key) - Still a php noob unfortunately. Thanks for any pointers.

It's a little unclear, but just create an array from the two and use the a index:
$log = array($arr1, $arr2);
foreach($log as $values) {
echo $values['a']; // 6:16pm
}
Or if you want the time as the index, then re-index on a:
$log = array($arr1, $arr2);
$log = array_column($log, null, 'a');
foreach($log as $time => $values) {
echo $time; // 6:16pm
echo $values['b']; // 2
}
It's prettier, but there is no need for the time as the index unless you are going to use ksort or access by index:
echo $log['6:16pm']['b'];

in cases that you don't know your key is recommended that you use foreach statement:
$logs = array();
$arr1 = array ('a'=>'6:16pm','b'=>2,'c'=>3,'d'=>4,'e'=>5);
$arr2 = array ('a'=>'6:24pm','b'=>20,'c'=>30,'d'=>40,'e'=>50);
$logs = array_merge($logs, array($arr1['a']=>$arr1));
$logs = array_merge($logs, array($arr2['a']=>$arr2)); //<-- to use time as key
$logs = array();
$arr1 = array('a' => '6:16pm', 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5);
$arr2 = array('a' => '6:24pm', 'b' => 20, 'c' => 30, 'd' => 40, 'e' => 50);
$logs = array_merge($logs, array($arr1['a'] => $arr1));
$logs = array_merge($logs, array($arr2['a'] => $arr2)); //<-- to use time as key
foreach ($logs as $time => $log) {
//index:
print_r($time);
//array:
print_r($log);
// a array key:
print_r($log['a']);
//go through all keys:
foreach ($log as $letter => $value) {
//index:
print_r($letter);
//value: a
print_r($value);
}
}

You can not call array like
print_r ($log[0]);
Because your array has key. which is 6:16pm for first one and 6:24pm for second. you have to call it by key name you have assigned. your array should be called like this in everywhere even in loop
print_r ($log["6:16pm"]);

Related

Need to get unique values in array

Array
(
)
Array
(
)
Array
(
[0] => 14
)
Array
(
[0] => 14
)
Array
(
[0] => 14
)
Array
(
[0] => 14
)
Array
(
[0] => 14
)
Array
(
[0] => 14
[1] => 12
)
I want this array
Array
(
[0] => 14
[1] => 12
)
Here is my code:
$colorarray = array();
foreach($catIds as $catid){
$colorarray[] = $catid;
}
Need to get unique array values
Thanks
You can use call_user_func_array with array-merge for flatten your array and then use array-unique as:
$res = call_user_func_array('array_merge', $arr);
print_r(array_unique($res)); // will give 12 and 14
Live example 3v4l
Or as #Progrock suggested: $output = array_unique(array_merge(...$data)); (I like that syntax using the ...)
You can always do something like this:
$colorarray = array();
foreach($catIds as $catid){
if(!in_array($catid, $colorarray) {
$colorarray[] = $catid;
}
}
But also this has n*n complexity, So if your array is way too big, it might not be the most optimised solution for you.
You can do following to generate unique array.
array_unique($YOUR_ARRAY_VARIABLE, SORT_REGULAR);
this way only unique value is there in your array instead of duplication.
UPDATED
This is also one way to do same
<?php
// define array
$a = array(1, 5, 2, 5, 1, 3, 2, 4, 5);
// print original array
echo "Original Array : \n";
print_r($a);
// remove duplicate values by using
// flipping keys and values
$a = array_flip($a);
// restore the array elements by again
// flipping keys and values.
$a = array_flip($a);
// re-order the array keys
$a= array_values($a);
// print updated array
echo "\nUpdated Array : \n ";
print_r($a);
?>
Reference link
Hope this will helps you
I have updated your code please check
$colorarray = array();
foreach($catIds as $catid){
$colorarray[$catid] = $catid;
}
This will give you 100% unique values.
PHP: Removes duplicate values from an array
<?php
$fruits_list = array('Orange', 'Apple', ' Banana', 'Cherry', ' Banana');
$result = array_unique($fruits_list);
print_r($result);
?>
------your case--------
$result = array_unique($catIds);
print_r($result);
You can construct a new array of all values by looping through each sub-array of the original, and then filter the result with array_unique:
<?php
$data =
[
[
0=>13
],
[
0=>13
],
[
0=>17,
1=>19
]
];
foreach($data as $array)
foreach($array as $v)
$all_values[] = $v;
var_export($all_values);
$unique = array_unique($all_values);
var_export($unique);
Output:
array (
0 => 13,
1 => 13,
2 => 17,
3 => 19,
)array (
0 => 13,
2 => 17,
3 => 19,
)

Randomly select words from multi-dimension array

I have a multi-dimensional array and from where i want to choose 11 different words. Each word from different array index.
Here is the array link: My multi-dimensional array
array (
'w' =>
array (
0 => 'walls',
1 => 'well',
2 => 'why',
),
'e' =>
array (
0 => 'end',
),
'a' =>
array (
0 => 'advantage',
1 => 'afford',
2 => 'affronting',
3 => 'again',
4 => 'agreeable',
5 => 'ask',
6 => 'at',
),
'c' =>
array (
0 => 'children',
1 => 'civil',
2 => 'continual',
)
);
My Desire Output:
From w => well
From e => end
From a => again
and so on.
Output like: array(well, end, again, ...) as array.
Use the following code:
$f = array_keys($result); // grouping the indices, namely, the characters
$a = "";
for($c=0;$c<count($f);$c++){
$a .= $f[$c];
} // grouping the indices stored in array $f to a string, $a
$words = array();
for($c=0;$c<11;$c++){
$random = $a[rand(0,strlen($a)-1)];
$k = $result[$random];
// $k stores the array of the character index, stored in $result
$random2 = rand(0,count($k)-1);
$words[$c] = $k[$random2];
// choose a word from a given character array
$a = preg_replace("/".$random."/","",$a);
// remove the character from $a to prevent picking words which start with the same character
}
print_r($words);
I've tested and it was proved working
https://3v4l.org/qi1VP
You can achieve this usin array_rand() function :
PHP
$words = [];
$limit = 3; //Replace this with your limit, 11
$count = 0;
shuffle($array);
foreach($array as $key => $value) {
$words[] = $value[array_rand($value)];
$count++;
if ($limit == $count) {
break;
}
}
EvalIn
Check Online, and let me know.
using shuffle and array_slice you can get what you want.
A shuffle function makes your array random, and array slice slice 11 sub array from it.
Array slice takes 3 argument, first one is the array, second one is the offset from where you want to start and last one how much you need to cut.
$words = array();
shuffle($result);
$res = array_slice($result, 0, 11);
foreach($res as $key => $value){
shuffle($value);
$words[] = $value[0];
}
print_r($words);

Combine Indexed arrays with the same keys

I am using the Flot jQuery plugin to create a graph on how many visitors there have been per platform. I would like to create a 4th line with total visitors, calculated by previously retrieved data.
I need to combine several multi-dimensional Indexed arrays, but not simply merging them recursively. I.E:
$arr1 = [[2016/05/04,2],[2016/05/03,4],[2016/05/02,6]];
$arr2 = [[2016/05/04,1],[2016/05/03,3],[2016/05/02,2]];
$arr3 = [[2016/05/04,6],[2016/05/03,7],[2016/05/02,8]];
The output should be:
$arrTotal = [[2016/05/04,9],[2016/05/03,14],[2016/05/02,16]];
How do I accomplish this in a (fairly) simple way?
First of all, you cannot declare your dates the way you did:
$arr1 = [[2016/05/04,2],[2016/05/03,4],[2016/05/02,6]];
Because it's going to take 2016, divide it by 5 then divide it by 4. You need to put them into quotes.
$arr1 = [['2016/05/04',2],['2016/05/03',4],['2016/05/02',6]];
But to create an associative array, you should do it this way:
$arr1 = array('2016/05/04' => 2, '2016/05/03' => 4, '2016/05/02' => 6);
$arr2 = array('2016/05/04' => 1, '2016/05/03' => 3, '2016/05/02' => 2);
$arr3 = array('2016/05/04' => 6, '2016/05/03' => 7, '2016/05/02' => 8);
Now all you want to do, is loop through each array and sum them up.
$merge = array();
function mergeArray(Array &$merge, Array $array){
// Loop through each key and value
foreach($array as $key => $value)
// Make sure the value is numeric
if(is_numeric($value)){
if(!isset($merge[$key]))
$merge[$key] = $value;
else
$merge[$key] += $value;
}
}
mergeArray($merge, $arr1);
mergeArray($merge, $arr2);
mergeArray($merge, $arr3);
And now if you dump the $merge:
array(3) {
["2016/05/04"]=>
int(9)
["2016/05/03"]=>
int(14)
["2016/05/02"]=>
int(16)
}
Build a method that will sum the values by respecting the keys of existing values.
$arr1 = array('2016/05/04'=>2,'2016/05/03'=>4,'2016/05/02'=>6);
$arr2 = array('2016/05/04'=>1,'2016/05/03'=>3,'2016/05/02'=>2);
$arr3 = array('2016/05/04'=>2,'2016/05/03'=>7,'2016/05/02'=>8);
function array_sum(&$new_arr,$arr) {
foreach ($arr as $date_key => $num_value) {
// initialize date in new array with 0, if not done previously
if (! isset($new_arr[$date_key])) { $new_arr[$date_key] = 0; }
// add number for indexed element of array
$new_arr[$date_key] += $num_value;
}
}
$new_arr = array();
array_sum($new_array,$arr1);
array_sum($new_array,$arr2);
array_sum($new_array,$arr3);
You are trying to sum up every second value from each nested array relatively to their position in the parent array.There's a short and simple solution using array_map, array_sum and array_column functions:
$groupped = array_map(null, $arr1,$arr2,$arr3);
$result = array_map(function($v){
return [$v[0][0], array_sum(array_column($v, 1))];
}, $groupped);
print_r($result);
The output:
Array
(
[0] => Array
(
[0] => 2016/05/04
[1] => 9
)
[1] => Array
(
[0] => 2016/05/03
[1] => 14
)
[2] => Array
(
[0] => 2016/05/02
[1] => 16
)
)

Replace IDs inside array with PHP

I have an array like this:
Array
(
[1] => Array
(
[uris] => Array
(
[1] => /
[2] => /news/
[3] => /about/
[4] => /contact/
)
[templates] => Array
(
[1] => 1
[2] => 2
[3] => 3
[4] => 4
)
)
)
and I need to update all the IDs with a new set of values so the final output should be something like:
[uris] => Array
(
[100] => /
[101] => /news/
[102] => /about/
[103] => /contact/
)
[templates] => Array
(
[100] => 1
[101] => 2
[102] => 3
[103] => 4
)
I think I might need to use a regex pattern like '/(\[.*?\])/' but I'm not sure how to put it together to get the final updated output.
EDIT: I should mention that the IDs I'm updating to won't be in sequential order, they're coming from a database table of entries in a CMS. Entries are being duplicated so they'll have the same URIs but the second set with have a higher set of IDs than the original ones.
There won't be a rule for the second set of IDs. The only guarantee is that the second set will all be higher than the highest ID from the first set.
The CMS I'm working with allows me to duplicate entries for use on a second site. But the CMS also uses a third party module that creates a serialized array like I've posted above which matches URIs against templates. The module doesn't create a new serialized array of the new entry IDs when the entries get duplicated, so what's I'm trying to do manually.
I thought I could unserialize the array, update the string's old IDs with the corresponding IDs of the new entries, reserialize it, and then copy it back into the database.
Array (
[1] => /
[2] => /news/
[3] => /about/
[4] => /contact/
)
Given this kind of array, what you need to do to replace the keys is simply:
$array = array_combine(range(100, 100 + (count($array) - 1)), $array);
It generates keys [100, .., 103] and splices them into the array.
You might have to loop and then replace the keys :
foreach ($yourArray as $array) {
for ($i = 0; $i < count($array['uris']); $i++) {
$array['uris'][$i][$newkey] = $array['uris'][$i][$oldkey];
unset($array['uris'][$i][$oldkey]);
}
for ($i = 0; $i < count($array['templates']); $i++) {
$array['templates'][$i][$newkey] = $array['templates'][$i][$oldkey];
unset($array['templates'][$i][$oldkey]);
}
}
As per your question update; not too sure what you're trying to do, but I have two guesses.
arr2d_replace_id will take all the uris and increase key and also a new set of array with updated keys and it's value.
arr2d_replace_id2 will 1) flip array of templates - where I'm guessing the value represents the ID of route in uris and so flipped to preserve values; 2) increase key value on uris; 3) change flipped array's value according to the key based on uris; 4) flip the array back with the new set info and assign to result.
function arr2d_replace_id($arr, $inc) {
$result = array();
foreach ($arr['uris'] as $k=>$v) {
$result['uris'][intval($k) + $inc] = $v;
$result['templates'][intval($k) + $inc] = $arr['templates'][$k];
}
return $result;
}
function arr2d_replace_id2($arr, $inc) {
$result = array();
$tpl_flipped = array_flip($arr['templates']);
foreach ($arr['uris'] as $k=>$v) {
$result['uris'][intval($k) + $inc] = $v;
$tpl_flipped[$k] = intval($k) + $inc;
}
$result['templates'] = array_flip($tpl_flipped);
return $result;
}
$test = array(
'uris' => array(
1 => '/', '/news/', '/about/', '/contact/',
),
'templates' => array(
1 => 1, 2, 3, 4
)
);
print_r( $test );
print_r( arr2d_replace_id($test, 100) );
print_r( arr2d_replace_id2($test, 100) );
See in action: http://3v4l.org/T6hHD
If the array values are unique, you can use array_flip:
$array = [
1 => '/',
2 => '/contact/',
3 => '/about/'
];
$counter = 100;
$array = array_flip($array);
$array = array_map(function($oldKey) use (&$counter) {
return ++$counter;
}, $array);
$array = array_flip($array);
$mainArray = array();
$mainArray[]=array("uris" => array("/", '/news', '/about', '/contact') , "templates" => array(1,2,3,4));
foreach ($mainArray as &$array) {
$uris = $array['uris'];
$keys = array_keys($uris);
for($i=0;$i<count($keys);$i++)
{
$uris[$keys[$i] + 100]=$uris[$i];
unset($uris[$i]);
}
$template = $array['templates'];
$keys = array_keys($uris);
for($i=0;$i<count($keys);$i++)
{
$template[$keys[$i] + 100]=$template[$i];
unset($template[$i]);
}
$array['uris'] = $uris;
$array['templates'] = $template;
}
echo "<pre>";
print_r($mainArray);
exit;
Try this one,
$array = array(
array('uris' => array(
'1' => '/',
'2' => '/news/',
'3' => '/about/',
'4' => '/contact/'
),
'templates' => array
(
'1' => '1',
'2' => '2',
'3' => '3',
'4' => '4'
)
)
);
$val = 100;
$result = array();
foreach ($array as $key => $value) {
foreach ($value as $key1 => $value1) {
foreach ($value1 as $key2 => $value2) {
$result[$key][$key1][$val] = $value2;
$val++;
}
}
}
var_dump($result);

php create multidimensional array from flat one

I have an array like this:
<?php
$array = array( 0 => 'foo', 1 => 'bar', ..., x => 'foobar' );
?>
What is the fastest way to create a multidimensional array out of this, where every value is another level?
So I get:
array (size=1)
'foo' =>
array (size=1)
'bar' =>
...
array (size=1)
'x' =>
array (size=1)
0 => string 'foobar' (length=6)
<?php
$i = count($array)-1;
$lasta = array($array[$i]);
$i--;
while ($i>=0)
{
$a = array();
$a[$array[$i]] = $lasta;
$lasta = $a;
$i--;
}
?>
$a is the output.
What exactly are you trying to do? So many arrays of size 1 seems a bit silly.
you probably want to use foreach loop(s) with a key=>value pair
foreach ($array as $k=>$v) {
print "key: $k value: $v";
}
You could do something like this to achieve the array you asked for:
$newArray = array();
for ($i=count($array)-1; $i>=0; $i--) {
$newArray = array($newArray[$i]=>$newArray);
}
I'm confused about what you want to do with non-numeric keys (ie, x in your example). But in any case using array references will help
$array = array( 0 => 'foo', 1 => 'bar', x => 'foobar' );
$out = array();
$curr = &$out;
foreach ($array as $key => $value) {
$curr[$value] = array();
$curr = &$curr[$value];
}
print( "In: \n" );
print_r($array);
print( "Out : \n" );
print_r($out);
Prints out
In:
Array
(
[0] => foo
[1] => bar
[x] => foobar
)
Out :
Array
(
[foo] => Array
(
[bar] => Array
(
[foobar] => Array
(
)
)
)
)
You can use a recursive function so that you're not iterating through the array each step. Here's such a function I wrote.
function expand_arr($arr)
{
if (empty($arr))
return array();
return array(
array_shift($arr) => expand_arr($arr)
);
}
Your question is a little unclear since in your initial statement you're using the next value in the array as the next step down's key and then at the end of your example you're using the original key as the only key in the next step's key.

Categories