I have the following array imported from a CSV:
Array
(
[0] => Array
(
[0] => QUARTERLY STATS;Q1/2011;Q2/2011;Q3/2011;Q4/2011;Q1/2012;Q2/2012;Q3/2012;Q4/2012;Q1/2013;Q2/2013;Q3/2013;Q4/2013;Q1/2014
)
[1] => Array
(
[0] => January;7500;8800;9500;10000;10500;11000;11500;12000;12500;13000;13420;13820;14200
)
[2] => Array
(
[0] => ;;17
[1] => 30%;8%;5
[2] => 30%;5%;4
[3] => 80%;4
[4] => 50%;4
[5] => 30%;4
[6] => 20%;4%;3
[7] => 20%;3%;2
[8] => 70%
)
[3] => Array
(
[0] => TOTAL;7500;8500;9500;11000;12500;11400;11800;13000;12500;13000;13420;13820;14200
)
[4] => Array
(
[0] => ;;17
[1] => 30%;7
[2] => 95%;5
[3] => 26%;5%;4
[4] => 76%;4
[5] => 55%;4
[6] => 35%;4
[7] => 17%;4%;3
[8] => 23%;2
[9] => 98%;2
[10] => 75%
)
So,
I would like to get rid of all arrays containing "% and TOTAL".
I thought to loop through and unset the matching case:
$remove ="TOTAL";
foreach ($csv as $key => $value){
if (in_array($remove,$value[$key])){
unset($value[$key]);
}
}
This is the error I got:
Warning: in_array() expects parameter 2 to be array, null given
My PHP Version 5.3.10
Would you do it that way or would you use the array_filter?
I am browsing since 2 hours the forum but I could not find any hint helping me out.
Cheers.
You can try by preg_replace for removing TOTAL & %. If you want to remove the element from array then use unset & finally use array_filter for removing null elements.
$newArr = array();
foreach($arr as $key=>$value){
foreach($value as $k=>$v){
$newArr[$key][$k] = preg_replace('/(TOTAL)|(%)/', '', $v); //for removing TOTAL & %
unset($arr[$key][$k]); //for unset the array elements that contains TOTAL & %
}
}
//Output by replacement
print '<pre>';
print_r($newArr);
print '</pre>';
//output after using unset
print '<pre>';
print_r(array_filter($arr));
print '</pre>';
In your case:
foreach ($csv as $subArray)
{
for ($i = 0, $len = count($subArray); $i < $len; $i++)
{
if (strpos($subArray[$i], $remove) !== false)
unset($subArray[$i])
}
}
Comments:
strict comparasion for strpos, if we use !=, then 0 position would be equals to false.
inner loop is "for-loop" bevause it's better to avoid changing content of array inside foreach.
$arr[][] = ("QUARTERLY STATS;Q1/2011;Q2/2011;Q3/2011;Q4/2011;Q1/2012;Q2/2012;Q3/2012;Q4/2012;Q1/2013;Q2/2013;Q3/2013;Q4/2013;Q1/2014");
$arr[][] = ("January;7500;8800;9500;10000;10500;11000;11500;12000;12500;13000;13420;13820;14200");
$arr[] = array(";;17","30%;8%;5","30%;5%;4","80%;4","50%;4","30%;4","20%;4%;3","20%;3%;2","70%");
$arr[][] = ("TOTAL;7500;8500;9500;11000;12500;11400;11800;13000;12500;13000;13420;13820;14200");
$arr[] = array("30%;7","95%;5","26%;5%;4","76%;4","55%;4","35%;4","17%;4%;3","23%;2","98%;2","75%");
$newArr = array();
foreach($arr as $key=>$value) {
foreach($value as $k=>$v) {
$newArr[$key][$k] = preg_replace('/(TOTAL)|(%)/', '', $v); //for removing TOTAL & %
unset($arr[$key][$k]); //for unset the array elements that contains TOTAL & %
}
unset($arr[$key]); // IT does not unset ARR[2] ARR[3] and ARR[4] containing TOTAL & %
}
Output by replacement
print '<pre>';
print_r($newArr);
print '</pre>';
Output after using unset
print '<pre>';
print_r(array_filter($arr));
print '</pre>';
I did create exactly the same ARRAY as imported from CSV.
unset does not unset ARRAY2,3,4 which is containing TOTAL AND %.
unset does not unset ARRAY2,3,4 which is containing TOTAL AND %.
Related
This question already has answers here:
How to merge two arrays by summing the merged values [duplicate]
(3 answers)
Closed 5 months ago.
I would like to merge array by conditions. If array keys match then add the values, if not then retain the value.
Here are my arrays:
Array1
(
[1] => 199
[3] => 1306
[5] => 199
)
Array2
(
[3] => 199
[4] => 199
)
My desired result is:
Result
(
[1] => 199
[3] => 1505
[4] => 199
[5] => 199
)
I used if-else conditions, but it's repeating the value which is already matched.
Here is my coding attempt:
$all=array();
foreach($sall as $sskey => $ssvalue){
foreach($upgradesall as $uukey => $uuvalue){
//$sskey==$uukey?$all[] = array("id"=>$sskey, "amount"=>$ssvalue+$uuvalue):($sskey!=$uukey? $all[] = array("id"=>$sskey, "amount"=>$ssvalue):($uukey!=$sskey?$all[] = array("id"=>$uukey, "amount"=>$uuvalue):''));
if($sskey===$uukey){
$all[] = array("id"=>$sskey, "amount"=>$ssvalue+$uuvalue);
}elseif($sskey!=$uukey){
$all[] = array("id"=>$sskey, "amount"=>$ssvalue);
}elseif($uukey!=$sskey){
$all[] = array("id"=>$uukey, "amount"=>$uuvalue);
}
}
}
I think the problem is simpler than it looks. You really only need a conditional to preclude undefined offset notices. Just iterate all keys and values in both arrays and add the values to the corresponding key in the merged array.
foreach ([$a1, $a2] as $a) { // iterate both arrays
foreach ($a as $key => $value) { // iterate all keys+values
$merged[$key] = $value + ($merged[$key] ?? 0); // merge and add
}
}
Really, the line that actually does the addition ($merged[$key] = $value + ($merged[$key] ?? 0);) could be reduced to $merged[$key] += $value;. That would still work, but it would produce a bunch of undefined offset notices. So instead we can set the key equal to the value plus either the previous value (if it exists) or zero.
If you're still using PHP 5, you can use a ternary instead of the null coalescing operator (??), like this:
$merged[$key] = $value + (isset($merged[$key]) ? $merged[$key] : 0);
The output won't be in the same order shown in your desired result, but you can use ksort($merged); to accomplish that
First you can merge the arrays by merging all values in the same key:
$allKeys = array_unique(array_merge(array_keys($arr1),array_keys($arr2)));
$result = [];
foreach ($allKeys as $key) {
$result[$key] = [];
if (array_key_exists($key,$arr1)) {
$result[$key][] = $arr1[$key];
}
if (array_key_exists($key,$arr2)) {
$result[$key][] = $arr2[$key];
}
}
This will result in:
Array
(
[1] => Array
(
[0] => 199
)
[3] => Array
(
[0] => 1306
[1] => 199
)
[5] => Array
(
[0] => 199
)
[4] => Array
(
[0] => 199
)
)
Then you can map them according to your conditions:
$endResult = array_map('array_sum',$result);
Result:
Array
(
[1] => 199
[3] => 1505
[5] => 199
[4] => 199
)
If you want the keys to be sorted you can run them through a ksort as well
Check the code:
http://sandbox.onlinephpfunctions.com/code/3eb23310f0fd8de8174a5caf8b2b91d4b7562b6b
You could achieve that by
$all = array_merge($arr1,$arr2); // existing elements in arr1 are replaced by arr2 else merge into new array_merge
//then add replaced elememnts value
foreach($arr1 as $k=>$v)
{
if(array_key_exists($k,$all))
{
$all[$k] = $all[$k] + $v;
}
}
I'm trying to display my array in groups of 3 elements, sorted by the last element of each group.
My array:
$info = array('goal','raul','80','foul','moneer','20','offside','ronaldo','60');
My expected output is:
1-foul moneer 20
2-offside ronaldo 60
3-goal raul 80
Sorted by the last value of the element groups.
I'm using foreach to display it:
$i = 0;
foreach($info as $key => $val) {
$i++;
echo $info[$key] . '<br>';
if ($i % 3 == 0){
echo "<br />";
}
Is this possible ? And if yes, how can I change my code to get my expected output?
This should work for you:
First we array_chunk() your array into chunks of 3 elements, so your array will have this structure:
Array
(
[0] => Array
(
[0] => goal
[1] => raul
[2] => 80
)
[1] => Array
(
[0] => foul
[1] => moneer
[2] => 20
)
[2] => Array
(
[0] => offside
[1] => ronaldo
[2] => 60
)
)
After this we sort it by the last value (here key 2), with usort() by simply comparing the values. Then at the end you can just loop through your array and display the data.
<?php
$info = array('goal','raul','80','foul','moneer','20','offside','ronaldo','60');
$arr = array_chunk($info, 3);
usort($arr, function($a, $b){
return $a[2] <=> $b[2];
});
foreach($arr as $k => $v)
echo ($k+1) . "-" . implode(" ", $v) . "<br>";
?>
output:
1-foul moneer 20
2-offside ronaldo 60
3-goal raul 80
I am fetching some data from the db and then push them to an array. I need to find the count of some strings and print out the result (count) in an efficient way:
Array
(
[0] => q1-1,q2-2,q3-2,q4-1,q5-2,q6-3,q7-1,q8-4,
[1] => q1-1,q2-2,q3-1,q4-3,q5-3,q6-3,q7-2,q8-1,
[2] => q1-1,q2-1,q3-1,q4-1,q5-1,q6-2,q7-2,q8-2,
[3] => q1-3,q2-1,q3-1,q4-1,q5-2,q6-3,q7-1,q8-1,
[4] => q1-2,q2-2,q3-3,q4-1,q5-3,q6-3,q7-1,q8-1,
[5] => q1-1,q2-2,q3-3,q4-1,q5-2,q6-3,q7-1,q8-1,
[6] => q1-3,q2-1,q3-1,q4-3,q5-2,q6-3,q7-2,q8-4,
[7] => q1-2,q2-2,q3-3,q4-1,q5-2,q6-5,q7-1,q8-1,
[8] => q1-1,q2-1,q3-2,q4-3,q5-3,q6-5,q7-1,q8-1,
[9] => q1-2,q2-1,q3-1,q4-1,q5-3,q6-3,q7-1,q8-1,
[10] => q1-3,q2-2,q3-3,q4-3,q5-4,q6-3,q7-1,q8-1,
...
)
Sample data is above.
I need to know how many occurences of q1-1, q1-2 ... q8-4 is in the array and print out readable version. Ex. The are 23: q1-1, 412: q1-2 and so on.
I was going to create an array of each string that needs to be searched that iterate through the array. For every result increment the resultVariable for that string but I'm not sure if that's the best way.
Suggestions?
Pretty simple, loop on your array, create sub arrays, and create a counter array:
$counts = array () ;
foreach ( $your_array as $row ) {
$sub = explode(',', $row);
foreach ( $sub as $subval ) {
if ( array_key_exists ( $subval, $counts ) ) {
$counts[$subval] ++ ;
} else {
$counts[$subval] = 1 ;
}
}
}
Here is $counts:
Array (
'q1-1' => 23,
'q1-2' => 9,
// and so on....
);
Try:
$arr = array(...); //your array
$count = array();
foreach($arr as $v) {
$substr = explode(',', $v);
foreach($substr as $m) {
if(strstr($v, $m) !== FALSE)
$count[$m]++;
}
}
Printing the counts,
foreach($count as $k => $v)
echo "Count for '$k': ". $v;
I have some data in the database, in this format:
Description~Level||Description~Level||
I want to transform this into an array where description is the Key & Level the value of the array.
$perso1 = explode('||', $myLevels['perso']);
$perso = array_slice($perso1, 0 , -1);
so far ive done this and it return that :
Array ( [0] => ffghtr~54644
[1] => ffghtr~54644
[2] => ffghtr~54644
[3] => ffghtr~54644
[4] => ffghtr~54644
[5] => ffghtr~54644 )
Now I cannot find a way to replace the array keys (0,1,2,etc) by my description.
Any idea ?
Thanks very much in advance.
$tmp = explode('||', $myLevels['perso']);
foreach ($tmp as $str) {
// this check is to remove empty elements from the list ..
// because your list ends with "||" there is a last empty element
if(strpos($str, "~") === false) continue;
// split by "~" into $key and $value
list($key, $value) = explode("~", $str, 2);
$result[$key] = $value;
}
print_r($result);
Please note that in the posted example you always have the same key: "ffghtr".
Because array keys are unique, you will end up replacing the content of this key with every iteration, having only the last element as the result.
$array = Array ( [0] => ffghtr~54644
[1] => ffghtr~54644
[2] => ffghtr~54644
[3] => ffghtr~54644
[4] => ffghtr~54644
[5] => ffghtr~54644 )
$new_array = new Array();
foreach($array as $a)
$new_array[(split('~',$a))[0]] = (split('~',$a))[1]
So new_array should be in the form you want. Actually i did not test the code but you got the idea. Please note the array you posted has always the same key: ffghtr.
So yuo'll end up with a new_array of only one element...
I got this array:
array (
0 => 'K.',
1 => 'Vrachtschip',
2 => 'L.',
3 => 'Gevechtsschip',
4 => 'Z.',
5 => 'Gevechtsschip',
6 => 'Kruiser',
7 => 'Slagschip',
8 => 'Bommenwerper',
9 => 'Vernietiger',
10 => 'Interceptor.',
)
of can I merge the items [0] with [1], because K. vrachtschip must be together.
same ass [2] and [3]; and [4] with [5]. if there is 1 letter and then a dot (k.) it must be merged with the following array item.
Anyone that can help me :)?
How about:
$arr = array (
'K.',
'Vrachtschip',
'L.',
'Gevechtsschip',
'Z.',
'Gevechtsschip',
'Kruiser',
'Slagschip',
'Bommenwerper',
'Vernietiger',
'Interceptor',
'B.',
);
$concat = '';
$result = array();
foreach ($arr as $elem) {
if (preg_match('/^[A-Z]\.$/', $elem)) {
$concat = $elem;
continue;
}
$result[] = $concat.$elem;
$concat = '';
}
if ($concat) $result[] = $concat;
print_r($result);
output:
Array
(
[0] => K.Vrachtschip
[1] => L.Gevechtsschip
[2] => Z.Gevechtsschip
[3] => Kruiser
[4] => Slagschip
[5] => Bommenwerper
[6] => Vernietiger
[7] => Interceptor
[8] => B.
)
Try to use a regular expression to test all entries of your array.
If an occurence is founded, concat the value of your entrie with the next.
I would try something like this:
for($idx=0, $max = count($array_in); $idx < $max; $idx++)
{
if(preg_match('/^[a-z]\.$/i', $array_in[$idx]))
{
$array_out[] = $array_in[$idx].$array_in[$idx+1];
$idx++;
}
else
{
$array_out[] = $array_in[$idx];
}
}
I'd probably do the following (pseudo code):
Create empty array for result
Iterate the original array
For each value: does it match /^[a-z]\.$/i?
If yes, see if original array contains a next element?
If yes, concatenate the two items and add to resulting array, skip next item in loop
If no (pt. 4 or 5) add directly to resulting array.