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;
Related
I have this array:
Array
(
[0] => Array
(
[0] => 1
[1] => a,b,c
)
[1] => Array
(
[0] => 5
[1] => d,e,f
)
)
I want the final array to be this:
Array
(
[0] => Array
(
[0] => 1
[1] => a
)
[1] => Array
(
[0] => 1
[1] => b
)
[2] => Array
(
[0] => 1
[1] => c
)
[3] => Array
(
[0] => 5
[1] => d
)
[4] => Array
(
[0] => 5
[1] => e
)
[5] => Array
(
[0] => 5
[1] => f
)
)
This is what I did:
<?php
$array = array(array(1,"a,b,c"),array(5,"d,e,f"));
$temp=array();
$count = 0;
foreach($array as $arr){
$rows = explode(",",$arr[1]);
foreach($rows as $row){
$temp[$count] = $arr;
$temp[$count][1] = $row;
$count++;
}
}
print_r($temp);
?>
This totally works but I was wondering if there was a better way to do this. This can be very slow when I have huge data.
Try like this way...
<?php
$array = array(array(1,"a,b,c"),array(5,"d,e,f"));
$temp=array();
$count = 0;
foreach($array as $arr){
$rows = explode(",",$arr[1]);
foreach($rows as $row){
$temp[$count][] = $arr[0];
$temp[$count][] = $row;
$count++;
}
}
/*print "<pre>";
print_r($temp);
print "<pre>";*/
?>
Here's a functional approach:
$result = array_merge(...array_map(function(array $a) {
return array_map(function($x) use ($a) {
return [$a[0], $x];
}, explode(",", $a[1]));
}, $array));
Try it online.
Or simply with two loops:
$result = [];
foreach ($array as $a) {
foreach (explode(",", $a[1]) as $x) {
$result[] = [$a[0], $x];
}
}
Try it online.
Timing these reveals that a simple loop construct is ~8 times faster.
functional: 4.06s user 0.08s system 99% cpu 4.160 total
loop: 0.53s user 0.05s system 102% cpu 0.561 total
If you need other way around,
$array = array(array(1, "a,b,c"), array(5, "d,e,f"));
$temp = [];
array_walk($array, function ($item, $key) use (&$temp) {
$second = explode(',', $item[1]);
foreach ($second as $v) {
$temp[] = [$item[0], $v];
}
});
print_r($temp);
array_walk — Apply a user supplied function to every member of an array
Here is working demo.
I have to arrays I would like to compare:
$original and $duplicate.
for example here is my original file:
print_r($original);
Array ( [0] => cat423 [1] => dog456 [2] => horse872 [3] => duck082 )
and here is my duplicate:
print_r($dublicate);
Array ( [0] => cat423 [1] => dug356 )
I compare them with array_diff:
$result = array_diff($original, $dublicate);
My result:
Array ( [1] => dog456 [2] => horse872 [3] => duck082 )
So far so good, but I need to make a difference between the values which are incorrect and the values which are completely missing. Is this possible?
A way would be to crawl the entire original array, afterwards you will have two arrays, missings and duplicates.
$original = array("cat423", "dog456", "horse872", "duck082");
$duplicate = array("cat423", "dug356");
$missings = $duplicates = array();
foreach ($original as $val) {
if (in_array($val, $duplicate))
$duplicates[] = $val;
else
$missings[] = $val;
}
If you need the keys as well, you would have to alter the foreach loop like so:
foreach ($original as $key=>$val) {
if (in_array($val, $duplicate))
$duplicates[] = array("key" => $key, "value" => $val);
else
$missings[] = array("key" => $key, "value" => $val);
}
use in_array function
$original = array("cat423", "dog456", "horse872", "duck082");
$duplicate = array("cat423", "dug356");
foreach ($original as $item) {
if(in_array($item, $duplicate))
{
$dup[] = $item;
}
else
{
$miss[] = $item;
}
}
print_r($miss); #Array ( [0] => dog456 [1] => horse872 [2] => duck082 )
print_r($dup); #Array ( [0] => cat423 )
Working Preview
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 %.
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);
Looking to loop through an array of URLs and inject each keyword from a second array into each URL but can't get to grips with the understanding of arrays. Eg:
$key = array("Keyword+1", "Keyword+2", "Keyword+3"),
$url =array("google.co.uk/#hl=en&q=", "bing.com/search?q=","uk.search.yahoo.com/search?vc=&p="),
I'd like the above to output:
google.co.uk/#hl=en&q=Keyword+1
google.co.uk/#hl=en&q=Keyword+2
google.co.uk/#hl=en&q=Keyword+3
bing.com/search?q=Keyword+1
bing.com/search?q=Keyword+2
bing.com/search?q=Keyword+3
uk.search.yahoo.com/search?vc=&p=Keyword+1
uk.search.yahoo.com/search?vc=&p=Keyword+2
uk.search.yahoo.com/search?vc=&p=Keyword+3
Is there an efficient way to achieve this? :)
foreach($url as $currenturl)
{
foreach($key as $currentkey)
{
echo $currenturl . $currentkey . '\n';
}
}
try this
Here is how you can do that:
$keys = array("Keyword+1", "Keyword+2", "Keyword+3");
$urls =array("google.co.uk/#hl=en&q=", "bing.com/search?q=","uk.search.yahoo.com/search?vc=&p=");
$my_array = array();
foreach($urls as $url)
{
foreach($keys as $key)
{
$my_array[] = $url . $key;
}
}
print_r($my_array);
Result:
Array
(
[0] => google.co.uk/#hl=en&q=Keyword+1
[1] => google.co.uk/#hl=en&q=Keyword+2
[2] => google.co.uk/#hl=en&q=Keyword+3
[3] => bing.com/search?q=Keyword+1
[4] => bing.com/search?q=Keyword+2
[5] => bing.com/search?q=Keyword+3
[6] => uk.search.yahoo.com/search?vc=&p=Keyword+1
[7] => uk.search.yahoo.com/search?vc=&p=Keyword+2
[8] => uk.search.yahoo.com/search?vc=&p=Keyword+3
)
You first want to loop over the $url array, then for each item in the $url array, you also want to loop over all the keys in the $key array and append them to the item you picked from $url,
foreach ($url as $u)
{
foreach ($key as $k)
{
echo $u.$k."\n";
}
}
What you're describing is a generalization of the outer product.
It would be more interesting to define a higher order function for this:
/**
* A generalization of the outer product, forming all the possible
* combinations of the elements of the two arrays and feeding them
* to $f.
* The keys are disregarded
**/
function array_outer($f, array $array1, array $array2) {
$res = array();
foreach ($array1 as $e1) {
$cur = array();
foreach ($array2 as $e2) {
$cur[] = $f($e1, $e2);
}
$res[] = $cur;
}
return $res;
}
$f = function ($a,$b) { return $a.$b; };
print_r(array_outer($f, array("a","b","c"), array("1", "2", "3")));
gives:
Array
(
[0] => Array
(
[0] => a1
[1] => a2
[2] => a3
)
[1] => Array
(
[0] => b1
[1] => b2
[2] => b3
)
[2] => Array
(
[0] => c1
[1] => c2
[2] => c3
)
)
See Mathematica's Outer.