I have about 5.000 record, each record contain an array like this
Array
(
[0] => 96
[1] => 40
[2] => 86
[3] => 17
[4] => 18
[5] => 23
)
Array
(
[0] => 01
[1] => 21
[2] => 96
[3] => 33
[4] => 44
[5] => 02
)
I want to get how many time element appear consecutively and into array like this
array (
[96]=>2, // number 96 appear 2 time consecutively
[40]=>1,
[86]=>1,
[17]=>1,
[18]=>1,
....
)
Any idea for this problem ???
To count the max number of times any given element appears consecutively, assuming your 5,000 arrays are in an array called $arr:
$count = array();
foreach ($arr as $k => $ar) {
foreach (array_unique($ar) as $a) {
$tmp = 1;
if (isset($count[$a])) {
$tmp = $count[$a];
}
$count[$a] = 1;
if ($k > 0) {
$i = 1;
while ($i <= $k && in_array($a, $arr[$k - $i])) {
$count[$a]++;
$i++;
}
}
if ($count[$a] < $tmp) $count[$a] = $tmp;
}
}
See demo
Related
What i am attempting to do is something like this
[Col-3][Col-3][Col-3][Col-3]
[Col-4][Col-4][Col-4]
[Col-3][Col-3][Col-3][Col-3]
I am continuing this with a foreach statement, but without luck at the moment.
Currently i'm just doing something like this.
$post = new mm_post();
$rows = $post->getAllPosts();
$i = 1;
foreach ($rows as $key => $row) {
if ($i % 4 == 0) {
echo "[Col-3] <br>";
} else {
echo "[Col-4] <br>";
}
$i++;
}
I am looking for a solution and explanation for this :)
Obviously atm it just make every 3 post [col-3] but i want it to make 4 col-3 then 3 col-4 is what i am looking for.
So I hope you guys can help me! :)
Think about every 7 posts makes 2 lines...one with 4 cols and one with 3 cols:
so when the $i counter is divisible by 7 you print a < br>. Then when line element is less then 4 print col-3,when is 4 print col-3 and < br> otherwise print col-4
$post = new mm_post();
$rows = $post->getAllPosts();
$i = 1;
$line=0;
for($rows as $key => $row)
{
if($i-($line*7)<4)
{
echo "[col-3]";
}
else if($i-($line*7)==4)
{
echo "[col-3]<br>";
}
else
{
echo "[col-4]";
}
if($i%7==0)
{
echo "<br>";
$line++;
}
$i++;
}
function alternate_slices($arr) {
$slices = array();
$start = 0;
$length = 4;
while ($start < count($arr)) {
$slices[] = array_splice($arr, $start, $length);
$length = (4 - $length + 3);
}
return $slices;
}
$arr = range(1, 20);
$sliced_arr = alternate_slices($arr);
<!-- print_r($sliced_arr);
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
[1] => Array
(
[0] => 5
[1] => 6
[2] => 7
)
[2] => Array
(
[0] => 8
[1] => 9
[2] => 10
[3] => 11
)
[3] => Array
(
[0] => 12
[1] => 13
[2] => 14
)
[4] => Array
(
[0] => 15
[1] => 16
[2] => 17
[3] => 18
)
[5] => Array
(
[0] => 19
[1] => 20
)
) -->
$sliced_arr = array_map(
function ($slice) {
return implode("||", $slice);
},
$sliced_arr
);
<!-- print_r($sliced_arr);
Array
(
[0] => 1||2||3||4
[1] => 5||6||7
[2] => 8||9||10||11
[3] => 12||13||14
[4] => 15||16||17||18
[5] => 19||20
) -->
$sliced_arr = implode("\n", $sliced_arr);
<!-- print($sliced_arr);
1||2||3||4
5||6||7
8||9||10||11
12||13||14
15||16||17||18
19||20 -->
Read about:
array_splice
array_map
implode
This is how $myArray looks like:
Array
(
[0] => Array
(
[month] => 1
[atual] => 0.00
)
[1] => Array
(
[month] => 2
[atual] => 11970.99
)
[2] => Array
(
[month] => 3
[atual] => 2888.00
)
[3] => Array
(
[month] => 5
[atual] => 1500.00
)
)
I want to "fill the gaps" of the months. That is, for those months, where we have no data (4,6,8,9,10,11,12), I want the [atual] to be zero.
I tried:
$novo=array();
for ($i=1; $i <=12 ; $i++) {
$mes=$myArray[$i-1]['month'];
$atual=$myArray[$i-1]['atual'];
if(!$mes){
$novo[$i]=0;
} else{
$novo[$i]=$atual;
}
};
But this is returning:
Array
(
[1] => 0.00
[2] => 11970.99
[3] => 2888.00
[4] => 1500.00
[5] => 0
[6] => 0
[7] => 0
[8] => 0
[9] => 0
[10] => 0
[11] => 0
[12] => 0
)
[edit] now i see you have another problem, your $myArray indexes aren't matching the months.
$myArray(
array('month' => 1, 'atual' => 0.00),
array('month' => 2, 'atual' => 11970.99),
array('month' => 3, 'atual' => 2888.00),
array('month' => 5, 'atual' => 1500.00)
)
for($i = 1; $i <= 12; $i++){
$novo[$i] = 0;
}
foreach($myArray as $item){
$novo[$item['month']] = $item['atual'];
}
print_r($novo);
This worked:
$novo=array_fill(1,12,0);
for ($i=1; $i <=12 ; $i++) {
$mes=$myArray[$i-1]['month'];
$atual=$myArray[$i-1]['atual'];
$novo[$mes]=$atual;
};
With this code you get the month 1 in position 1 (not in position 0);
Also you only search in the array one time.
It's not a beautiful solution but...
$my_array = array(
array('month'=>3,'actual'=>100)
);
$results =array();
for($i=1;$i<13;$i++){
$results[$i] = 0;
}
foreach($my_array as $a){
$results[$a['month']] = $a['actual'];
}
print_r($results);
PHP has several functions that deal with sorting arrays, and here is a comparison of array's sorting functions
I didn't fully understand your question in the first response. This code should work for you. First we will create a temporary array just to hold the month and the data in an accessible format. Then we create your array :
$temp=array();
// Populate the temp array
foreach ($myArray as $row) {
if (is_array($row) && isset($row["month"])) {
$temp[$row["month"]] = $row["atual"];
}
}
// Create novo array
for ($i=0; $i <12 ; $i++) {
$novo[$i]["month"] = $i+1;
if (array_key_exists($i+1, $temp)) {
$novo[$i]['atual'] = $temp[$i+1];
} else {
$novo[$i]['atual'] = 0;
}
}
I have a very large data set that I'm trying to find the smallest set that will satisfy all the data sets. The final set must have one value in it that is in all of the data sets
A small sample of the data looks like
[0] => Array
(
[0] => 21
[1] => 21
[2] => 21
)
[1] => Array
(
[0] => 29
)
[2] => Array
(
[0] => 27
)
[3] => Array
(
[0] => 21
[1] => 21
[2] => 21
[3] => 39
[4] => 39
[5] => 43
)
[4] => Array
(
[0] => 29
[1] => 33
[2] => 33
[3] => 43
)
In this case I need logic to return 21, 27 and 29
The values returned needs to be be the minium number of values that match all arrays. Since I'm a PHP programmer, I writing this function in PHP.
You could follow this algorithm:
Updated after testing
$data=array(
array(21,29,27,57,22),
array(22,21,23,24,25,26),
array(31)
);
$map = array(); // keep a map of values and how many times they occur in other sets
foreach ($data as $setid => $set) {
foreach (array_unique($set) as $v) {
$map[$v][$setid] = true;
}
}
function reverseCount(array $a, array $b)
{
return count($b) - count($a);
}
// sort reversed on intersection count
uasort($map, 'reverseCount');
// after sorting the first number will be the one that occurs the most
// keep track of which sets have been hit
$setmap = array(); $n = count($data);
foreach ($map as $v => $sets) {
$hits = 0;
foreach ($sets as $setid => $dummy) {
if (!isset($setmap[$setid])) {
--$n;
++$hits;
$setmap[$setid] = true;
} else {
continue;
}
}
if ($hits) {
echo "value $v\n";
if (!$n) {
// all sets are hit
break;
}
}
}
Tested this time. It's not proven to always get the right result, because this is considered a greedy approximation algorithm.
But I hope it gives an idea of what you could do. Let me know if anything confuses you or if I'm dead wrong about it :)
I have these two arrays result in print_r:
Array ( [0] => multidesign1 [1] => multidesign1 [2] => multidesign2 [3] => multidesign2 )
Array ( [0] => 30 [1] => 7 [2] => 40 [3] => 1 )
The actual contents should be:
multidesign1 has 30 and 7 so its 37 while multidesign2 has 40 and 1 so its 41.
Can I combine these two arrays so I could come up with multidesign1=>37 and multidesign2=>41 ?
Thanks.
$newArray = array();
foreach(range(0, count($firstArray) - 1) as $index) {
if(isset($newArray[$index])) {
$newArray[$index] += $secondArray[$index];
} else {
$newArray[$index] = $secondArray[$index];
}
}
Is that something like what you're looking for?
$result = array();
foreach ($array1 as $i => $key) {
$result[$key] += $array2[$i];
}
i have an array like:
Array ( [0] => #!A1#DC [1] => #IMSR102.71/74.82 [2] => #HV50 [3] => #PR7/7/ [4] => #RX0 [5] => #ERN/1//0 [6] => #Q2 [7] => #!A1#DC [8] => #IMSR102.50/74.82 [9] => #HV40 [10] => #PR5/5/ [11] => #RX0 [12] => #ERN/1//1 [13] => #Q2 etc etc with hundreds o values
i get this array from a file (with the function file($filename) ) and i need to split it in many subarray.
"!A1#DC" this is the beginning of a series of values that ends with #Q2 but the number of the values between the beginning and the end is not always the same and the only 2 values that are same are the two given ("!A1#DC" for the beginning and "#Q2" for the end)
how can i get somethings like this?
Array (
[0] => Array ( [0] => #!A1#DC [1] => #IMSR102.71/74.82 [2] => #HV50 [3] => #PR7/7/ [4] => #RX0 [5] => #ERN/1//0 [6] => #Q2 )
[1] => Array (
[1] => #!A1#DC [2] => #IMSR102.50/74.82 [3] => #HV40 [4] => #PR5/5/ [5] => #RX0 [6] => #ERN/1//1 [7] => #Q2 etc etc
could you please help me?
thanks
Loop through an array. When you meet starting value, store it's index. When you meet ending value, use array_slice() to extract the part between the last pair of starting and ending values, store this part into another array.
$source = array (
'#!A1#DC',
'#IMSR102.71/74.82',
'#HV50',
'#PR7/7/',
'#RX0',
'#ERN/1//0',
'#Q2',
'#!A1#DC',
'#IMSR102.50/74.82',
'#HV40',
'#PR5/5/',
'#RX0',
'#ERN/1//1',
'#Q2',
);
$dest = array();
$startValue = '#!A1#DC';
$endValue = '#Q2';
$startIndex = 0;
foreach ( $source as $index => $value ) {
if ( $value === $startValue ) {
$startIndex = $index;
} else
if ( $value === $endValue ) {
$dest[] = array_slice($source, $startIndex, $index - $startIndex + 1);
}
}
print_r($dest);
Basically you need to loop through each element of $input, collecting those within START and END elements into a separate array:
$input = array("#!A1#DC", "A", "B", "#Q2");
$values = array();
$current = 0;
define("START", "#!A1#DC");
define("END", "#Q2");
for ($i = 0; $i < count($input); $i++) {
if ($input[$i] == END) {
// Ignore any elements after this point until we see START
$current = null;
} else if ($input[$i] == START) {
// Create a new current collection array
$current = count($values);
$values[$current] = array();
} else {
// Store the value if we are collecting
if ($current !== null) {
$values[$current][] = $input[$i];
}
}
}