How to split a multidimensional array in PHP? - php

How can I take a multi-dimensional array like the below, and split it into multiple separate arrays? Additional challenge: Although I know there are two pairs in the example below (pageviews, visits), how can you do it assuming that you don't know the number of pairs in the array? For example, I may want to add "time on page" or "pages visited", and could therefore have any number of pairs.
My goal, in the end, would be to have an array like: "26, 9, 18" and another array "20, 4, 9".
I've got an array like this:
Array
(
[20090817] => Array
(
[ga:pageviews] => 26
[ga:visits] => 20
)
[20090818] => Array
(
[ga:pageviews] => 9
[ga:visits] => 4
)
[20090819] => Array
(
[ga:pageviews] => 18
[ga:visits] => 9
)
)
I would have thought the below code would work, but it doesn't get the specific value that I want, and for some weird reason, it trims each value to one character:
$pageViews = array();
$visits[] = array();
foreach ($google_lastMonth as $value) {
foreach ($value as $nested_key => $nested_value) {
$pageViews[] = $nested_value["ga:pageviews"];
$visits[] = $nested_value["ga:visits"];
}
}

Your array is not as deep as you think:
$pageViews = array();
$visits = array();
foreach ($google_lastMonth as $value) {
$pageViews[] = $value["ga:pageviews"];
$visits[] = $value["ga:visits"];
}

I think
you should erase the braket on visit
Ok my bad should be that
$pageViews = array();
$visits = array();
foreach ($result as $value) {
$pageViews[] = $value['ga:pageviews'];
$visits[] = $value['ga:visits'];
}

Related

Count how many times a value appears in this array?

I have this php array named $ids:
Array (
[0] => Array ( [id] => 10101101 )
[1] => Array ( [id] => 18581768 )
[2] => Array ( [id] => 55533322 )
[3] => Array ( [id] => 55533322 )
[4] => Array ( [id] => 64621412 )
)
And I need to make a new array containing each $ids id value, as the new keys, and the times each one appears, as the new values.
Something like this:
$newArr = array(
10101101 => 1,
18581768 => 1,
55533322 => 2,
64621412 => 1,
);
This is what I have:
$newArr = array();
$aux1 = "";
//$arr is the original array
for($i=0; $i<count($arr); $i++){
$val = $arr[$i]["id"];
if($val != $aux1){
$newArr[$val] = count(array_keys($arr, $val));
$aux1 = $val;
}
}
I supose array_keys doesn't work here because $arr has the id values in the second dimension.
So, how can I make this work?
Sorry for my bad english and thanks.
array_column will create an array of all the elements in a specific column of a 2-D array, and array_count_values will count the repetitions of each value in an array.
$newArr = array_count_values(array_column($ids, 'id'));
Or do it by hand like this where $arr is your source array and $sums is your result array.
$sums = array();
foreach($arr as $vv){
$v = $vv["id"];
If(!array_key_exists($v,$sums){
$sums[$v] = 0;
}
$sums[$v]++;
}
You can traverse your array, and sum the id appearance, live demo.
$counts = [];
foreach($array as $v)
{
#$counts[$v['id']] += 1;
}
print_r($counts);

Remove duplicates from a multi-dimensional array based on 2 values

I have an array that looks like this
$array = array(
array("John","Smith","1"),
array("Bob","Barker","2"),
array("Will","Smith","2"),
array("Will","Smith","4")
);
In the end I want the array to look like this
$array = array(
array("John","Smith","1"),
array("Bob","Barker","2"),
array("Will","Smith","2")
);
The array_unique with the SORT_REGULAR flag checks for all three value. I've seen some solutions on how to remove duplicates based on one value, but I need to compare the first two values for uniqueness.
Simple solution using foreach loop and array_values function:
$arr = array(
array("John","Smith","1"), array("Bob","Barker","2"),
array("Will","Smith","2"), array("Will","Smith","4")
);
$result = [];
foreach ($arr as $v) {
$k = $v[0] . $v[1]; // considering first 2 values as a unique key
if (!isset($result[$k])) $result[$k] = $v;
}
$result = array_values($result);
print_r($result);
The output:
Array
(
[0] => Array
(
[0] => John
[1] => Smith
[2] => 1
)
[1] => Array
(
[0] => Bob
[1] => Barker
[2] => 2
)
[2] => Array
(
[0] => Will
[1] => Smith
[2] => 2
)
)
Sample code with comments:
// array to store already existing values
$existsing = array();
// new array
$filtered = array();
foreach ($array as $item) {
// Unique key
$key = $item[0] . ' ' . $item[1];
// if key doesn't exists - add it and add item to $filtered
if (!isset($existsing[$key])) {
$existsing[$key] = 1;
$filtered[] = $item;
}
}
For fun. This will keep the last occurrence and eliminate the others:
$array = array_combine(array_map(function($v) { return $v[0].$v[1]; }, $array), $array);
Map the array and build a key from the first to entries of the sub array
Use the returned array as keys in the new array and original as the values
If you want to keep the first occurrence then just reverse the array before and after:
$array = array_reverse($array);
$array = array_reverse(array_combine(array_map(function($v) { return $v[0].$v[1]; },
$array), $array));

how to check multiple items are in an array or not with PHP

I'm reading an RTF file that gets uploaded by the user, I then exploded this file on each \pard to get each line and then preg_split each line into an array. I then loop over the array looking for a certain value and get the data next to it. All this is working fine but what's the best way to do this multiple times looking for multiple strings? Here is what I have so far:
$data = explode('\pard',$rtf);
foreach ($data as $item) {
$values = preg_split('/[\t]/', $item);
if (in_array('shipped yesterday', $values)){
$key = array_search('shipped yesterday', $values);
print $values[$key + 1];
}else{
print_r($values);
}
}
The RTF file looks like the following:
booked in yesterday 50 41 78
packaged yesterday 62 45 48
shipped yesterday 46 52 62
So my code above is looking for 'shipped yesterday' then getting the first value next to it, in this case 46.
What's the most efficient way to do it for the rest of the values 'booked in yesterday' and 'packaged yesterday'?
I think the fastest way would be a simple regex.
preg_match_all('/((?:booked in|packaged|shipped) yesterday)\s+(\d+)/i',$rtf,$matches);
$values = array();
foreach($matches[1] as $key => $match){
$values[$match] = $matches[2][$key];
}
print_r($values);
This will parse all matching the given pattern into an array as such
Array (
['booked in yesterday'] => '50'
['packaged yesterday'] => '62'
['shipped yesterday'] => '46'
)
Note if you need the numeric value just parse before passing into the array
$values[$match] = intval($matches[2][$key]);
The output from matches would be like this just to clarify the building of the array:
Array (
[0] => Array (
[0] => 'booked in yesterday 50'
[1] => 'packaged yesterday 62'
[2] => 'shipped yesterday 46'
)
[1] => Array (
[0] => 'booked in yesterday'
[1] => 'packaged yesterday'
[2] => 'shipped yesterday'
)
[2] => Array (
[0] => '50'
[1] => '62'
[2] => '46'
)
)
Your code looks fine to me, you could take an excerpt and use it as a function. HOWEVER, as you asked about efficiency, it's worth noting that isset is faster than in_array
For example...
function checkForValue($searchterm, $values) {
if (isset($values[$searchterm]))
return $values[$searchterm];
}else{
return "$searchterm not found";
}
}
$data = explode('\pard',$rtf);
foreach ($data as $item) {
$values = preg_split('/[\t]/', $item);
print checkForValue('shipped yesterday', $values);
print checkForValue('packaged yesterday', $values);
}
Maybe you could try running another foreach within an array of the required test strings ?
Have a look at this :-
<?php
$checkString = array("shipped yesterday","booked in yesterday","packaged yesterday");
$data = explode('\pard',$rtf);
foreach ($data as $item)
{
$values = preg_split('/[\t]/', $item);
foreach($checkString as $check)
{
if (in_array($check, $values))
{
$key = array_search($check, $values);
print $values[$key + 1];
}
else
{
print_r($values);
}
}
}
?>

Convert CSV string to Array keys and a value of 1 or true

Please could someone help find a better solution to the code below.
Here is my existing solution:
$list = '54,78,3,5';
$list = explode(",",$list);
foreach($list as $k => $v) { $compare[$v] = 1; }
when i run array_flip instead of the foreach on $list it returns an array like this:
Array(
54 => 0,
78 => 1,
...
)
I need this so another array which is already in this format can be compared with an IF statment:
Array(
54 => 1,
78 => 1,
...
)
$list = '54,78,3,5';
$list = explode(",",$list);
$array = array_combine($list, array_fill(0, count($list), 1));
print_r($array);
Array
(
[54] => 1
[78] => 1
[3] => 1
[5] => 1
)
array_fill() will create an array with all of its values being the number 1 at the same size as the $list array. array_combine() then creates a new array with the values of $list as the keys and the values created by array_fill();
Demo
Do you need the original $list to be a variable? Can't you just make it an array from the start wherever the data comes from, and append 1 or true to the value?
Otherwise, before your current foreach, add a new loop and go through $list (which you made into an array) and make a new array appending the required value to each key (keys taken from $list):
foreach ($list as $key)
{
$new_array[$key] = 1;
}

How to setup a PHP multidimensional array and declare the array keys?

I need some help setting up a PHP array. I get a little lost with multidimensional arrays.
Right now, I have an array with multiple products as follows:
If I do: print_r($products['1']); I get:
Array ( [0] => size:large [1] => color:blue [2] => material:cotton )
I can do print_r($products['2']); , etc and it will show a similar array as above.
I am trying to get it where I can do this:
echo $products['1']['color']; // the color of product 1
...and echo "blue";
I tried exploding the string and adding it to the array as follows:
$step_two = explode(":", $products['1']);
foreach( $step_two as $key => $value){
$products['1'][$key] = $value;
}
I know I'm obviously doing the explode / foreach way wrong but I wanted to post my code anyway. I hope this is enough information to help sort this out.
Try this:
foreach ($products as &$product)
{
foreach ($product as $key => $value)
{
list($attribute, $val) = explode(':',$value);
$product[$attribute] = $val;
// optional:
unset($product[$key]);
}
}
?>
Here goes a sample that will convert from your first form to your desired form (output goes below)
<?php
$a = array( '1' => array('color:blue','size:large','price:cheap'));
print_r($a);
foreach ($a as $key => $inner_array) {
foreach ($inner_array as $key2 => $attribute) {
$parts = explode(":",$attribute);
$a[$key][$parts[0]] = $parts[1];
//Optional, to remove the old values
unset($a[$key][$key2]);
}
}
print_r($a);
?>
root#xxx:/home/vinko/is# php a.php
Array
(
[1] => Array
(
[0] => color:blue
[1] => size:large
[2] => price:cheap
)
)
Array
(
[1] => Array
(
[color] => blue
[size] => large
[price] => cheap
)
)
You would be better of to build the array the right way, but to solve your problem you need to explode in the loop, something like:
foreach( $products['1'] as $value){
$step_two = explode(":", $value);
$products['1'][$step_two[0]] = $step_two[1];
}
You can wrap another foreach around it to loop over your whole $products array.
And you'd also better build a new array to avoid having both the old and the new values in your $products array.
You are right: you got the "foreach" and "explode" the wrong way around. Try something like this:
foreach($products['1'] as $param => $value) {
$kv = explode(":", $value);
if(count($kv) == 2) {
$products[$kv[0]] = $kv[1];
unset($products['1'][$param]);
}
}
This code first loops over the sub-elements of your first element, then splits each one by the colon and, if there are two parts, sets the key-value back into the array.
Note the unset line - it removes array elements like $products['1'][1] after setting products['1']['color'] to blue.
If you already have $products structured in that way, you can modifty its structure like this:
$products = array(
'1' => array(
0 => 'size:large', 1 => 'color:blue', 2 => 'material:cotton'
),
'2' => array(
0 => 'size:small', 1 => 'color:red', 2 => 'material:silk'
),
);
foreach ($products as &$product) {
$newArray = array();
foreach ($product as $item) {
list($key, $value) = explode(':', $item);
$newArray[$key] = $value;
}
$product = $newArray;
}
print_r($products);
If you don't want to overwrite original $products array, just append $newArray to another array.
<?php
$products = array();
$new_product = array();
$new_product['color'] = "blue";
$new_product['size'] = "large";
$new_product['material'] = "cotton";
$products[] = $new_product;
echo $products[0]['color'];
//print_r($products);

Categories