I have a set of numbers e.g.
$input = array(1, 4, 7, 4, 9, 4, 8, 6, 2, 8, 7, 7, 4, 5, 3);
I am trying to work out the importance of each number based on the following rule:
As the sequence gets longer the numbers get less significant, and each time a number is mentioned then it will improve the relevance (how much depends on its position in the
sequence).
I am expecting something like:
Array(
'4' => 90%
'1' => 75%
'7' => 60%
....
)
So 4 is the most inportant, followed by 1 and then 7 etc. Note that the output is completely fabricated but gives in indication that 4 should be the most important. I believe I want some kind of linear solution.
Is this more of what you were thinking? Answer based on stillstanding
$numbers = array(1, 4, 7, 4, 9, 4, 8, 6, 2, 8, 7, 7, 4, 5, 3);
$weight = array();
$count = count($numbers);
for ($i=0; $i<$count; $i++) {
if (!isset($weight[$numbers[$i]])) $weight[$numbers[$i]] = 1;
$weight[$numbers[$i]] += $count + pow($count - $i, 2);
}
$max = array_sum($weight);
foreach ($weight as &$w) {
$w = ($w / $max) * 100;
}
arsort($weight);
result:
Array
(
[4] => 34.5997286296
[7] => 17.3677069199
[1] => 16.3500678426
[8] => 10.0407055631
[9] => 9.29443690638
[6] => 5.42740841248
[2] => 4.40976933514
[5] => 1.35685210312
[3] => 1.15332428765
)
$numbers=array(1, 4, 7, 4, 9, 4, 8, 6, 2, 8, 7, 7, 4, 5, 3);
$weight=array();
$count=count($numbers);
for ($i=0; $i<$count; $i++) {
if (!isset($weight[$numbers[$i]]))
$weight[$numbers[$i]]=1;
$weight[$numbers[$i]]*=$count-$i;
}
var_dump($weight);
Result:
Array
(
[1] => 15
[4] => 5040
[7] => 260
[9] => 11
[8] => 54
[6] => 8
[2] => 7
[5] => 2
[3] => 1
)
This algorithm is fairly simplistic, but I think it accomplishes what you're looking for.
Given that you have the sequence you described above and it is stored in an array called $sequence
$a = array();
for($i=0;$i<count($sequence);$i++)
{
//calculate the relevance = 1/position in array
$relevance = 1/($i+1);
//add $relevance to the value of $a[$sequence[$i]]
if(array_key_exists((string)$sequence[$i],$a))
$a[(string)$sequence[$i]] += $relevance;
else
$a[(string)$sequence[$i]] = $relevance;
}
return $a;
Related
I have 2 arrays like this
$head = array(7, 1, 1, 1, 1, 14, 14, 14, 9, 9, 9, 13, 13, 13, 3, 3, 5, 8, 8, 8, 2, 2); //count =22
$customer = array(1, 7, 9, 13, 14, 1, 9, 13, 1, 13, 14, 1, 9, 14, 2, 8, 8, 2, 3, 5, 3, 8); //count=22
And I want to group this 2 arrays by consider at $customer, if $customer[0]=1 in $customer[1-21] and $head[1-21] will not have a value 1, such as in the $head[1] have a value 1, So delete at $head[1] and $customer[1]. And then consider at $customer[6]. The value is 9. It means in $head[7-21] and $customer[7-21] will not have a value 9.
I am trying to write a code for this concept like this. Here is my code
for ($i = 0; $i < count($head); $i++) {
for ($j = $i + 1; $j < count($customer); $j++) {
if ($customer[$i] == $head[$j]) {
unset($head[$j]);
unset($customer[$j]);
}
if ($customer[$i] == $customer[$j]) {
unset($head[$j]);
unset($customer[$j]);
}
}
}
print_r($head);
print_r($customer);
the result is of $head and $customer is:
Array ( [0] => 7 [6] => 14 [7] => 14 [13] => 13 [14] => 3 [15] => 3 [16] => 5 [17] => 8 [18] => 8 [19] => 8 [20] => 2 [21] => 2 )
Array ( [0] => 1 [6] => 9 [7] => 13 [13] => 14 [14] => 2 [15] => 8 [16] => 8 [17] => 2 [18] => 3 [19] => 5 [20] => 3 [21] => 8 )
I found that it's wrong. Because the real result should be:
Array ( [0] => 7 [6] => 14 [7] => 14 [14] => 3 [15] => 3 )
Array ( [0] => 1 [6] => 9 [7] => 13 [14] => 2 [15] => 8 )
Please help me to fix this problem.
Your logic is all ok but when you unset a particular index then all other index after when you iterate it again then i index is missing. Just open the error and warning then you will see
Notice: Undefined offset
I have just replaced your uset to assign it to ''. So you can understand it
<?php
$head = array(7, 1, 1, 1, 1, 14, 14, 14, 9, 9, 9, 13, 13, 13, 3, 3, 5, 8, 8, 8, 2, 2); //count =22
$customer = array(1, 7, 9, 13, 14, 1, 9, 13, 1, 13, 14, 1, 9, 14, 2, 8, 8, 2, 3, 5, 3, 8); //count=22
for ($i = 0; $i < count($head); $i++) {
for ($j = $i + 1; $j < count($customer); $j++) {
if ($customer[$i] == $head[$j]) {
$head[$j] = '';
$customer[$j] = '';
}
if ($customer[$i] == $customer[$j]) {
$head[$j] = '';
$customer[$j] = '';
}
}
}
print_r(array_diff($head, [''])); // remove all the '' entries
print_r(array_diff($customer, [''])); // remove all the '' entries
The problem is that count() only returns a count of the set elements in the array. So if you unset them it will be reduced and you won't arrive at the end of the array. To fix, calculate the count at the start and store in a variable:
$headcount = count($head);
$customercount = count($customer);
for ($i = 0; $i < $headcount; $i++) {
for ($j = $i + 1; $j < $customercount; $j++) {
if ($customer[$i] == $head[$j]) {
unset($head[$j]);
unset($customer[$j]);
}
if ($customer[$i] == $customer[$j]) {
unset($head[$j]);
unset($customer[$j]);
}
}
}
So I have this JSON Array:
[0] => 238
[1] => 7
[2] => 86
[3] => 79
[4] => 55
[5] => 92
[6] => 55
[7] => 7
[8] => 254
[9] => 9
[10] => 75
[11] => 238
[12] => 89
[13] => 238
I will be having more values in the actual JSON file. But by looking at this I can see that 238 and 55 is being repeated more than any other number. What I want to do is get the top 5 most repeated values in the array and store them in a new PHP array.
$values = array_count_values($array);
arsort($values);
$popular = array_slice(array_keys($values), 0, 5, true);
array_count_values() gets the count of the number of times each item appears in an array
arsort() sorts the array by number of occurrences in reverse order
array_keys() gets the actual value which is the array key in the results from array_count_values()
array_slice() gives us the first five elements of the results
Demo
$array = [1,2,3,4,238, 7, 86, 79, 55, 92, 55, 7, 254, 9, 75, 238, 89, 238];
$values = array_count_values($array);
arsort($values);
$popular = array_slice(array_keys($values), 0, 5, true);
array (
0 => 238,
1 => 55,
2 => 7,
3 => 4,
4 => 3,
)
The key is to use something like array_count_values() to tally up the number of occurrences of each value.
<?php
$array = [238, 7, 86, 79, 55, 92, 55, 7, 254, 9, 75, 238, 89, 238];
// Get array of (value => count) pairs, sorted by descending count
$counts = array_count_values($array);
arsort($counts);
// array(238 => 3, 55 => 2, 7 => 2, 75 => 1, 89 => 1, 9 => 1, ...)
// An array with the first (top) 5 counts
$top_with_count = array_slice($counts, 0, 5, true);
// array(238 => 3, 55 => 2, 7 => 2, 75 => 1, 89 => 1)
// An array with just the values
$top = array_keys($top_with_count);
// array(238, 55, 7, 75, 89)
?>
I have this small problem although it's small i can't seem to work it out, I've set of data i need to display, lets say 1 to 17. i need to display 3 in a row like 1,2,3 in one row and 4,5,6 in the next because bootstrap row support 12 columns and there are 3 elements of 4 columns each.
Because the amount of data can vary and the total number of data won't divide by 3 like the example it's 17 how can I write something in PHP that will display the data 3 in a row and like in this example there will be 5 rows of 3 and a last row having 2 sets.
Thanks
Edit:
I didn't write any code of this but was thinking a loop and a nested loop but think that's too clunky any better way of doing this?
You can use following code :
for($i = 1;$i<=17;$i++){
if($i%3 !=1 && $i%3 != 0){
print_r($i." , ");
}else if( $i%3 == 0){
print_r($i);
}
else{
print_r("<br/>".$i." , ");
}
}
It'll give you output like this:
1 , 2 , 3
4 , 5 , 6
7 , 8 , 9
10 , 11 , 12
13 , 14 , 15
16 , 17 ,
Rukshan you can use the modulus operator.
You can use the code below as an example. I have mixed html and php, but it is just to show you an example:--
<?php
echo "<table>";
for($i=1;$i<18;$i++)
{
echo "<tr>";
echo "<td>".$i."</td>";
if($i%3 == 0) echo "</tr>";
}
echo "</table>";
?>
Try using array_slice() to slice your array as per your need. You will get your division in arrays. Loop through them to create your table.
Reference Example
$stores = array(1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12);
$division = ceil( count($stores) / 3 ); //to divide array into 3 halves
$firstHalf = array_slice($stores, 0, $division);
$secondHalf = array_slice($stores, $division, $division);
$thirdHalf = array_slice($stores, $division * 2);
Output for $stores = array(1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12)
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
Array
(
[0] => 5
[1] => 6
[2] => 7
[3] => 8
)
Array
(
[0] => 10
[1] => 11
[2] => 12
)
Output for $stores = array(1, 2, 3, 4, 5, 6, 7, 8, 10)
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
Array
(
[0] => 5
[1] => 6
[2] => 7
[3] => 8
)
Array
(
[0] => 9
[1] => 10
)
Output for $stores = array(1, 2, 3, 4, 5, 6, 7, 8);
Array
(
[0] => 1
[1] => 2
[2] => 3
)
Array
(
[0] => 4
[1] => 5
[2] => 6
)
Array
(
[0] => 7
[1] => 8
)
To divide the array in two halves you can use
$division = ceil( count($stores) / 2 );
$firstHalf = array_slice($stores, 0, $division);
$secondHalf = array_slice($stores, $division);
For example suppose I have
$input = array(0, 1, 2, 3, 4, 5, 6, 7);
How would I remove element 5 and insert at position 2 leaving me with
0, 1, 5, 2, 3, 4, 6, 7
$input = array(0, 1, 2, 3, 4, 5, 6, 7);
array_splice($input, 2, 0, array($input[5])); //Place the a new array in the 3rd place of array
unset($input[6]); //remove the fifth element
array_splice($input, 0, 0); //to update the indexes
echo "<pre>".print_r($input,1)."</pre>"; //to view the array
Method without the need to unset and rearrange the index
$input = array(0, 1, 2, 3, 4, 5, 6, 7);
array_splice($input, 2, 0, array_splice($input,5,1));
Output
Array
(
[0] => 0
[1] => 1
[2] => 5
[3] => 2
[4] => 4
[5] => 5
[6] => 6
[7] => 7
)
$input = array(0, 1, 2, 3, 4, 5, 6, 7);
$moved = array_splice($input, 5, 1);
array_splice($input, 2, 0, $moved);
You should take a look at the function array_splice:
http://www.php.net/manual/en/function.array-splice.php
That will remove elements from an array and also insert.
array_splice(); will do it for you http://www.php.net/manual/fr/function.array-splice.php
EDIT :
array_splice(your_array,position_where_you_want_to_replace_your_number,1,replacement_number);
Never used it before, may I've made a mistake above, but it's a start, insn't it? :)
EDIT2 : above, you'll have to remove the second number which is still here with my function.
I know this doesn't work but is there any way of autogenerating values? It can be pretty tedious to put so many values in specially if it's 50 or maybe 100 numbers...
Here's the code so you get my idea:
for ($num = 1; $num <= 20; $num++){
$arr = array($num);
echo $arr[2];
};
Solved: It was the range() and arrayfill(). :)
Take a look at the range() function.
>> $a = range(1, 10);
array (
0 => 1,
1 => 2,
2 => 3,
3 => 4,
4 => 5,
5 => 6,
6 => 7,
7 => 8,
8 => 9,
9 => 10,
)
>>
Or maybe array_fill()?
Are you talking about the rand() function? That surely exist ;)
PHP Rand Function