I have these tables. In the first table I have the transaction ID and the products bought in that transaction.
TID Products
1 1,2,5
2 2,4
3 2,3
4 1,2,4
5 1,3
6 2,3
7 1,3
8 1,2,3,5
9 1,2,3
What I want to do to this data is count the number of times an itemset occurs in the Products column. For example the itemset {1,2} is found 4 times in the Products column, there is no problem there, but 1,3 in only found 2 times but as it's seen in the Products column it appears 4 times.
ItemSet Sup. count
1,2 4
1,3 2
1,4 0
1,5 0
2,3 4
2,4 2
2,5 1
3,4 0
3,5 1
4,5 0
This is the php code that I used to find matches in the Sup. count column. if I make it find all coincidences in the itemset when I get to two digit numbers like 12 or more it will say that it found 1 and 2 again that is why I placed the boundary. So I am stuck at this place.
$result_support = array_fill ( 0 , $count_itemsets , 0 );
$count_result_array = count($result_array);
for($i = 0; $i < $count_itemsets; $i++){
for($j = 0; $j < $count_result_array; $j++){
$string = $result_array[$j];
if (preg_match('~\\b' . $result_itemset[$i] . '\\b~i', $string, $m)) {
$result_support[$i] = $result_support[$i] + 1;
}
}
}
$array1 = array(
1=> '1,2,5',
2 => '2,4',
3=> '2,3',
4 => '1,2,4',
5 => '1,3',
6=> '2,3',
7 => '1,3',
8 => '1,2,3,5',
9 => '1,2,3');
$produCt =array();
foreach ($array1 as $index =>$val){
$arra = explode(',', $val);
if(count($arra)>2){
for($i=0;$i<count($arra);$i++){
for($j=$i+1;$j<count($arra);$j++){
$produCt[] = $arra[$i].",".$arra[$j];
}
}
}else{
$produCt[] =$val;
}
}
$prdtCount =array_count_values($produCt);
var_dump($prdtCount);
I assume that your required output is
array (size=8)
'1,2' => int 4
'1,5' => int 2
'2,5' => int 2
'2,4' => int 2
'2,3' => int 4
'1,4' => int 1
'1,3' => int 4
'3,5' => int 1
Related
I have an array of id's and I want to filter those id's to last 5 and unique ids.
$recently_viewed_ids
array:16 [▼
0 => 1
1 => 2
2 => 1
3 => 2
4 => 8
5 => 7
6 => 6
7 => 6
8 => 6
9 => 5
10 => 8
11 => 4
12 => 1
13 => 1
14 => 1
15 => 1
]
Here is my code and it's messing up because I'm getting 85672
$items = array_slice(array_unique(array_reverse($recently_viewed_ids)), -5);
Output I am expecting
14856
You need to use next combination of array functions:
array_slice( // get first 5 values
array_unique( // get only unique values
array_reverse($arr) //reverse array for get last values
)
,0,5);
Code example here: PHPize.online
In Laravel, I believe you can rewrite the correct answer to:
return collect($arr)
->reverse()
->unique()
->slice(0, 5)
->all();
try this :
$items = array_slice(array_unique(array_reverse($recently_viewed_ids)), 5);
i have a text and i want convert it to array by exclude but i cant get true array
# SRC-ADDRESS DST-ADDRESS PACKETS BYTES SRC-USER DST-USER 0 10.40.47.48 216.58.205.211 12 822 2 1 10.40.47.48 102.132.97.21 66 9390 2 2 184.106.10.77 10.40.47.252 10 1819 1 3 10.40.47.252 104.27.155.225 1 41 1 4 10.40.47.252 144.76.103.6 5 878 1 5 102.132.97.35 10.40.47.252 11 1159 1 6 10.40.47.252 52.169.53.217 1 397 1 7 104.27.155.225 10.40.47.252 1 52 1
and i want result like this
Array
(
[0] => Array
(
[.id] => *0
[src-address] => 10.40.47.50
[dst-address] => 185.144.157.141
[packets] => 6
[bytes] => 1349
)
[1] => Array
(
[.id] => *1
[src-address] => 195.122.177.151
[dst-address] => 10.40.47.48
[packets] => 4
[bytes] => 174
[dst-user] => 2
)
....
i try this but it is wrong
$arr = exclude(" ",$text);
edit :
i can get text by another way
0 src-address=108.177.15.188 dst-address=10.40.47.252 packets=1 bytes=52 dst-user="1" 1 src-address=10.40.47.48 dst-address=172.217.19.150 packets=11 bytes=789 src-user="2" 2 src-address=184.106.10.77 dst-address=10.40.47.252 packets=26 bytes=5450 dst-user="1"
As I mentioned in the comments, one way would be to first explode your input by " " (space). You loop through each element/row of the resulting array. Then you explode each of those by = (equals sign). If the result of that explode is a single-element array, you know you should start a new row and create a key-value pair using your special .id key. If the count of the result is two, take the first part and make it the key of a new key-value pair in the current row, and take the second part and make it the value of that key-value pair.
There's a bit of a wrinkle in the fact that some of your source values are quoted, but you seem to want them not quoted in the result. To handle that we do a lose equality check on the value to see if it is the same when converted to an integer or not. If it is, then we convert it to remove the quotes.
$inputText = '0 src-address=108.177.15.188 dst-address=10.40.47.252 packets=1 bytes=52 dst-user="1" 1 src-address=10.40.47.48 dst-address=172.217.19.150 packets=11 bytes=789 src-user="2" 2 src-address=184.106.10.77 dst-address=10.40.47.252 packets=26 bytes=5450 dst-user="1"';
$result = array();
$spaceParts = explode(" ", $inputText);
foreach($spaceParts as $part)
{
$subParts = explode("=", $part);
if(count($subParts) == 1)
{
$resultIndex = (isset($resultIndex) ? $resultIndex+1 : 0);
$result[$resultIndex] = array(".id" => "*".$part);
}
else if(count($subParts) == 2)
{
$result[$resultIndex][$subParts[0]] = ((int)$subParts[1] == $subParts[1] ? (int)$subParts[1] : $subParts[1]);
}
else
{
// unexpected, handle however you want
}
}
print_r($result);
DEMO
Try reading the string in using str_getcsv replacing the delimiter with whatever the string is delimited by.
var_dump(str_getcsv($input, ","));
Note the manual states that the delimiter must be one char long. If wanting a tab or multiple spaces you will need to look into the answer:
str_getcsv on a tab-separated file
str-getcsv php manual
Here is something that could work but I would recoment using the csv methods instead to read the data in . And it is unclear how your data should be actually mapped to header.
$header = "# SRC-ADDRESS DST-ADDRESS PACKETS BYTES SRC-USER DST-USER ";
$input = "# SRC-ADDRESS DST-ADDRESS PACKETS BYTES SRC-USER DST-USER 0 10.40.47.48 216.58.205.211 12 822 2 1 10.40.47.48 102.132.97.21 66 9390 2 2 184.106.10.77 10.40.47.252 10 1819 1 3 10.40.47.252 104.27.155.225 1 41 1 4 10.40.47.252 144.76.103.6 5 878 1 5 102.132.97.35 10.40.47.252 11 1159 1 6 10.40.47.252 52.169.53.217 1 397 1 7 104.27.155.225 10.40.47.252 1 52 1 ";
$string = str_replace($header, "", $input );
$delimiter = " ";
$columns = 6;
$splitData = explode($delimiter, $string);
$result = [];
$i= 0;
foreach ($splitData as $key => $value) {
$result[$i][] = $value;
if (($key+1) % $columns == 0 ){
$i++;
}
}
var_dump($result);
Using the second example with the 0 src-address=108.177.15.188 dst-address=10.40.47.252 packets=1 bytes=52 dst-user="1" format, there are 6 entries:
$result = array_map(function($v) {
parse_str("id=".implode("&", $v), $output);
return $output;
}, array_chunk(explode(' ', $text), 6));
Explode the array on spaces
Chunk the array into 6 entries per element
Map to a function that implodes each array on & and parse it as a query string
The loop returns like this
value 1
value 2
value 3
value 4
value 5
value 6
value 7
value 8
value 9
value 10
The following should be my output
------------------------------
value 1
1
value 2
------------------------------
value 3
2
value 4
-------------------------------
value 5
3
value 6
-------------------------------
value 7
4
value 8
-------------------------------
value 9
5
value 10
--------------------------------
Can any one help I have searched lot more reference on internet.
You can use array_chunk() like below:
$cars=array("Volvo","BMW","Toyota","Honda","Mercedes","Opel");
echo "<pre>"; print_r(array_chunk($cars,2));
Output:
Array
(
[0] => Array
(
[0] => Volvo
[1] => BMW
)
[1] => Array
(
[0] => Toyota
[1] => Honda
)
[2] => Array
(
[0] => Mercedes
[1] => Opel
)
)
You can loop over your array and take two like so:
$test = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
for($i = 0; $i < count($test); $i += 2) {
$j = $i + 1;
echo "$test[$i] \n";
echo "$test[$j] \n";
}
The array is like this
$a = array(1,2,3,4,5,6,7,8);
After that in each iteration the 3rd element should be removed until it reaches to a single element
the iteration will be something like this
index:0 1 2 3 4 5 6 7
value:1 2 3 4 5 6 7 8
this is the normal one
index:0 1 2 3 4 5 6 7
value:1 2 4 5 7 8
here 3 and 6 removed as they came out as the 3rd elements
then after 6 is removed it should count 7 and 8 as 1st and 2nd and go to value 1 which makes 1 as the 3rd element.This continues until there is only one element remaining.
output
12345678
1245678
124578
24578
2478
478
47
7
7 is the remaining element
here is the code, hope it helps.
<?php
$array = [1,2, 3,4,5,6,7,8];
function removeAtNth($array, $nth)
{
$step = $nth - 1; //gaps between operations
$benchmark = 0;
while(isset($array[1]))
{
$benchmark += $step;
$benchmark = $benchmark > count($array) -1 ? $benchmark % count($array) : $benchmark;
echo $benchmark."\n";
unset($array[$benchmark]);
$array = array_values($array);
echo implode('', $array)."\n";
}
}
removeAtNth($array, 3);
result:
kris-roofe#krisroofe-Rev-station:~$ php test.php
1245678
124578
24578
2478
478
47
7
Your looking for array_chunk()
$a = array(1,2,3,4,5,6,7,8);
$thirds = array_chunk($a, 3);
$thirds now is like:
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[1] => Array
(
[0] => 4
[1] => 5
[2] => 6
)
[2] => Array
(
[0] => 7
[1] => 8
)
)
Then just loop through the $thirds array and array_pop() to grab the last value.
However, I'm not sure why you're looking to get 7 at the end and not 8. Can you explain?
I have these tables. In the first table I have the transaction ID and the products bought in that transaction.
TID Products
1 1,2,5
2 2,4
3 2,3
4 1,2,4
5 1,3
6 2,3
7 1,3
8 1,2,3,5
9 1,2,3
What I want to do to this data is count the number of times an itemset occurs in the Products column. For example the itemset {1,2} is found 4 times in the Products column, there is no problem there, but 1,3 in only found 2 times but as it's seen in the Products column it appears 4 times.
ItemSet Sup. count
1,2 4
1,3 2
1,4 0
1,5 0
2,3 4
2,4 2
2,5 1
3,4 0
3,5 1
4,5 0
This is the php code that I used to find matches in the Sup. count column. if I make it find all coincidences in the itemset when I get to two digit numbers like 12 or more it will say that it found 1 and 2 again that is why I placed the boundary. So I am stuck at this place.
$result_support = array_fill ( 0 , $count_itemsets , 0 );
$count_result_array = count($result_array);
for($i = 0; $i < $count_itemsets; $i++){
for($j = 0; $j < $count_result_array; $j++){
$string = $result_array[$j];
if (preg_match('~\\b' . $result_itemset[$i] . '\\b~i', $string, $m)) {
$result_support[$i] = $result_support[$i] + 1;
}
}
}
$array1 = array(
1=> '1,2,5',
2 => '2,4',
3=> '2,3',
4 => '1,2,4',
5 => '1,3',
6=> '2,3',
7 => '1,3',
8 => '1,2,3,5',
9 => '1,2,3');
$produCt =array();
foreach ($array1 as $index =>$val){
$arra = explode(',', $val);
if(count($arra)>2){
for($i=0;$i<count($arra);$i++){
for($j=$i+1;$j<count($arra);$j++){
$produCt[] = $arra[$i].",".$arra[$j];
}
}
}else{
$produCt[] =$val;
}
}
$prdtCount =array_count_values($produCt);
var_dump($prdtCount);
I assume that your required output is
array (size=8)
'1,2' => int 4
'1,5' => int 2
'2,5' => int 2
'2,4' => int 2
'2,3' => int 4
'1,4' => int 1
'1,3' => int 4
'3,5' => int 1