Find occurrences of length of words in array - php

I'm trying to find the number of occurrences length in array;
Here's what I've tried, but I don't know what to do after.
function instances_and_count($input) {
$arr = explode(' ', $input);
$count = 0;
$test = [];
foreach ($arr as $arr_str) {
if ($count != 0) {
$test = [$count => 'hi'];
print_r($test);
}
$count++;
}
}
$test = 'A heard you say something I know you ain\'t trying to take me homeboy.';
instances_and_count($test);
In this example, I explode a string to make an array. I need a count of let's say all words with a length of 1 which in this string it's a count of 2 (A and I); How can I do this for all lengths?

PHP's array functions are really useful here; we can convert our exploded array of strings to an array of string lengths using array_map and strlen, and then use array_count_values to count how many words of each length there are:
$test = 'A heard you say something I know you ain\'t trying to take me homeboy.';
$counts = array_count_values(array_map('strlen', explode(' ', $test)));
print_r($counts);
Output:
Array
(
[1] => 2
[5] => 2
[3] => 3
[9] => 1
[4] => 2
[6] => 1
[2] => 2
[8] => 1
)
Demo on 3v4l.org
Note that there is a length of 8 in this array for the "word" homeboy. This can be avoided either by stripping trailing punctuation from the string, or (better) using str_word_count to extract only whole words from the original string. For example (thanks #mickmackusa):
$test = 'I heard you say something I know you ain\'t trying to take me homeboy.';
$counts = array_count_values(array_map('strlen', str_word_count($test, 1)));
print_r($counts);
Output:
Array
(
[1] => 2
[5] => 2
[3] => 3
[9] => 1
[4] => 2
[6] => 1
[2] => 2
[7] => 1
)
Demo on 3v4l.org
If you want to output the array with keys in order, just use ksort on it first:
ksort($counts);
print_r($counts);
Output:
Array
(
[1] => 2
[2] => 2
[3] => 3
[4] => 2
[5] => 2
[6] => 1
[8] => 1
[9] => 1
)
This is not necessary for use within your application.

Use the length of the word as array key. For each word you are looping over, check if an array entry for that length already exists - if so, increase the value by one, otherwise initialize it with 1 at that point:
function instances_and_count($input) {
$words = explode(' ', $input);
$wordLengthCount = [];
foreach($words as $word) {
$length = strlen($word);
if(isset($wordLengthCount[$length])) {
$wordLengthCount[$length] += 1;
}
else {
$wordLengthCount[$length] = 1;
}
}
ksort($wordLengthCount);
return $wordLengthCount;
}
Result:
array (size=8)
1 => int 2
2 => int 2
3 => int 3
4 => int 2
5 => int 2
6 => int 1
8 => int 1
9 => int 1

Related

Finding all 1 digit and 2 digits numbers in a larger number using regex

I want to match all 1 digit and 2 digit numbers using regex.
Subject string: '12345'
Expected match: 1,2,3,4,5,12,23,34,45
I'm trying: \d(\d)? but as result i get 12,2,34,3,5
You can use
$s = "12345";
$res = [];
if (preg_match_all('~(?=((\d)\d?))~', $s, $m, PREG_SET_ORDER)) {
$single = []; $double = [];
foreach ($m as $v) {
if ($v[1] != $v[2]) {
array_push($single, $v[2]);
array_push($double, $v[1]);
} else {
array_push($single, $v[1]);
}
}
$res = array_merge($single, $double);
print_r( $res );
}
See the PHP demo. Output:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 12
[6] => 23
[7] => 34
[8] => 45
)
NOTES:
(?=((\d)\d?)) - a regex that captures into Group 1 two or one digits, and into Group 2 the first digit of the previous sequence
PREG_SET_ORDER groups the captures into the same parts of the match array
If the match is a single digit, the $double array is not modified
The final array is a combination of single digit array + double digit array.
I'm not so sure this can be done with regex as it will match 2 OR 1, then move on through the string.
So if it finds "12" at position 0, it will move to position 1 and find "2".
But if it finds "1" at position 0, it will move to position 1 and find "2" and never see "12".
I'm not sure if what it finds is random or not.
You can acheieve this with some PHP code though.
Loop through the characters and at each position ask...
Is this character numeric? If yes add to array.
Is this character and the next character numeric? If yes, concat both and add to array.
Then move to next position.
<?php
$string = '12345f67';
$chars = str_split($string);
$length = count($chars);
$numbers = [];
for ($i = 0; $i < $length; $i++) {
if (is_numeric($chars[$i])) {
$numbers[] = (int) $chars[$i];
if ($i < ($length - 1) && is_numeric($chars[$i + 1])) {
$numbers[] = (int) ($chars[$i].$chars[$i+1]);
}
}
}
print_r($numbers);
Results below of above code....
Array
(
[0] => 1
[1] => 12
[2] => 2
[3] => 23
[4] => 3
[5] => 34
[6] => 4
[7] => 45
[8] => 5
[9] => 6
[10] => 67
[11] => 7
)
Here is a straightforward solution:
$digits = '12345';
preg_match_all('/\d/', $digits, $single_digit_matches);
preg_match_all('/\d\d/', $digits, $two_digit_matches1);
preg_match_all('/\d\d/', substr($digits, 1), $two_digit_matches2);
$matches = array_merge($single_digit_matches[0], $two_digit_matches1[0], $two_digit_matches2[0]);
asort($matches);
print_r($matches);
The output is
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 12
[7] => 23
[6] => 34
[8] => 45
)

Search array input key in array

How do I find the keys array of disciplines that have appropriate values?
For Example:
$arr1 = [2, 4, 12];
$result = [...] // Var_dump in link
in_array($arr1, $result);
Regardless of their order, I need to see if there is a set of keys or a no.
But in_array() does not work.
Thanks!
Dump array
Update (01.03.2017)
This is my version of the solution to this problem
$findResult = array_filter($result, function($val)use($get){
$requiredDisciplines = [1, $get['disciplines']['second'], $get['disciplines']['third'], $get['disciplines']['four']]; // запрос
$activePriorities = [];
foreach ($val['disciplines'] as $discipline) {
if (in_array($discipline['id'], $requiredDisciplines)) {
$activePriorities[] = $discipline['priority'];
}
}
for ($i = 0; $i<3; $i++){
if(!in_array($i, $activePriorities))
return false;
}
/*if(in_array(0, $activePriorities) && in_array(1, $activePriorities) && in_array(2, $activePriorities) != true)
return false;*/
// print_r($activePriorities);
return true;
});
I've got a versatile one-liner that will give you all of the arrays containing matches. (so you can derive the keys or the count from that). (demo)
This function is only set to compare the values between the needle and the haystack, but can be set to search keys-values pairs by replacing array_intersect with array_intersect_assoc and adding ,ARRAY_FILTER_USE_BOTH to the end of the filter function (reference: 2nd snippet # https://stackoverflow.com/a/42477435/2943403)
<?php
// haystack array
$result[]=array(1,2,3,4,5,6,7,8,9,10,11,12);
$result[]=array(1,3,5,7,9,11);
$result[]=array(2,4,6,8,10,12);
// needle array
$arr1=array(2,4,12);
//one-liner:
$qualifying_array=array_filter($result,function($val)use($arr1){if(count(array_intersect($val,$arr1))==count($arr1)){return $val;}});
/*
// multi-liner of same function:
$qualifying_array=array_filter(
$result,
function($val)use($arr1){ // pass in array to search
if(count(array_intersect($val,$arr1))==count($arr1)){ // total pairs found = total pairs sought
return $val;
}
}
);*/
echo 'Total sub-arrays which contain the search array($arr1): ',sizeof($qualifying_array),"<br>";
echo 'Keys of sub-arrays which contain the search array($arr1): ',implode(',',array_keys($qualifying_array)),"<br>";
echo 'Is search array($arr1) in the $result array?: ',(sizeof($qualifying_array)?"True":"False"),"<br>";
echo "<pre>";
print_r($qualifying_array);
echo "</pre>";
The output:
Total sub-arrays which contain the search array($arr1): 2
Keys of sub-arrays which contain the search array($arr1): 0,2
Is search array($arr1) in the $result array?: True
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
[6] => 7
[7] => 8
[8] => 9
[9] => 10
[10] => 11
[11] => 12
)
[2] => Array
(
[0] => 2
[1] => 4
[2] => 6
[3] => 8
[4] => 10
[5] => 12
)
)

PHP create a Array

Does anyone know how I can create an Array?
$string = '3-1-0-1.11,3-1-1-1.12,3-1-2-1.13,3-1-3-1.14,3-2-0-1.02,3-2-1-1.03,3-2-2-1.04,3-2-3-1.05,3-2-4-1.06,3-3-0-3.23,3-3-1-3.24,3-3-2-3.25,3-3-3-3.26';
$array = explode(',', $string);
$last_entry = null;
foreach ($array as $current_entry) {
$first_char = $current_entry[2]; // first Sign
if ($first_char != $last_entry) {
echo '<h2>'. $first_char . '</h2><br>';
}
echo $current_entry[4] . '<br>';
$last_entry = $first_char;
}
I need an Array like this:
Array
(
[1] => Array
(
[0] => 0
[1] => 1
[2] => 2
)
[2] => Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
[4] => 4
[5] => 5
)
[3] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
)
The first number 3 and other numbers 3 after comma are not important.
Important numbers are second and third numbers in values of $array.
I need categories. Example: if the first (second) number is 1 create Category 1 and subcategory 1 where first (second) number actual is 1.
To create an an array, you need to declare it using array() feature. Below I have created a blank array.
$array = array();
An array with values looks like this
$array = array("string", "string2", "string3");
To add values in an array, you use the array_push method.
array_push($array, "string4");
On multidimensional arrays, declare the array then add the inner array, below is objct oriented
$array = array("string"=>array("innerstring", "innerstring2"), "string2" => array("innerstring3", "innerstring4"), "string3" => array("innerstring5", "innerstring6"));
and procedural
$array=array(array("string", "innerstring", "innerstring2",), array("string2", "innerstring3", "innerstring4"), array("string3", "innerstring5", "innerstring6"));
Try next script:
$string = '3-1-0-1.11,3-1-1-1.12,3-1-2-1.13,3-1-3-1.14,3-2-0-1.02,3-2-1-1.03,3-2-2-1.04,3-2-3-1.05,3-2-4-1.06,3-3-0-3.23,3-3-1-3.24,3-3-2-3.25,3-3-3-3.26';
foreach(explode(',', $string) as $tpl) {
$tpl = explode('-', $tpl);
$tpl[3] = explode('.', $tpl[3]);
$result[$tpl[1]][$tpl[2]][$tpl[3][0]] = !empty($tpl[3][1]) ? $tpl[3][1] : null;
}
var_dump($result);

Sort an integer array, negative integers in the front and positive integers in the back

I was given an array like this:
$input = array(-1,1,3,-2,2, 3,4,-4);
I neeed to sort it in such a way that negative integers are in the front and positive integers are at the back, and the relative position should not be changed. So the output should be:
$output = array(-1 ,-2,-4, 1,3,2,3,4);
I tried this using usort, but I could not retain the relative positions.
function cmp ($a, $b)
{
return $a - $b;
}
usort($input, "cmp");
echo '<pre>', print_r($input), '</pre>';
Array
(
[0] => -4
[1] => -2
[2] => -1
[3] => 1
[4] => 2
[5] => 3
[6] => 3
[7] => 4
)
Try this..
$arr = array(-1,1,3,-2,2, 3,4,-4);
$positive = array_filter($arr, function($x) { return $x > 0; });
$negative = array_filter($arr, function($x) { return $x < 0; });
sort($positive);
rsort($negative);
$sorted = array_merge($negative,$positive);
print_r($sorted);
Demo:https://eval.in/419320
Output:
Array
(
[0] => -1
[1] => -2
[2] => -4
[3] => 1
[4] => 2
[5] => 3
[6] => 3
[7] => 4
)
This is an ordering problem, but it's not a sort.
The problem can be broken down as follows:
Separate the given array into two arrays; one of negative numbers, the other of positive numbers. (Should consider where you want 0.) The order of items in each of those arrays should be the same as they appear in the input array.
Do this by pushing values, for example.
Concatenate the two arrays.

Array permutations in multidimensional array keeping the keys PHP

For two days I've been running crazy trying to accomplish this, maybe you can enlighten me. This is for a horse betting permutation. Every time a user plays, I get a multidimensional array (2 levels). The first level contains the race ID, the the second level contains thee horses selected by the user for that race. It looks like this:
$play = array
(
'4' => array(7, 32),
'8' => array(4),
'2' => array(9),
'12' => array('5'),
'83' => array('10', '11', '12', ''),
'9' => array('3'),
);
I need to know what are all the possible combinations for that play. Which is easily done with this function:
function permutations(array $array)
{
switch (count($array)) {
case 1:
return $array[0];
break;
case 0:
throw new InvalidArgumentException('Requires at least one array');
break;
}
$a = array_shift($array);
$b = permutations($array);
$return = array();
foreach ($a as $key => $v) {
if(is_numeric($v))
{
foreach ($b as $key2 => $v2) {
$return[] = array_merge(array($v), (array) $v2);
}
}
}
return $return;
}
This returns an array with all the possible combinations beautifully. So far so good, and the result looks like this:
Array
(
[0] => Array
(
[0] => 7
[1] => 4
[2] => 9
[3] => 5
[4] => 10
[5] => 3
)
[1] => Array
(
[0] => 7
[1] => 4
[2] => 9
[3] => 5
[4] => 11
[5] => 3
)
[2] => Array
(
[0] => 7
[1] => 4
[2] => 9
[3] => 5
[4] => 12
[5] => 3
)
[3] => Array
(
[0] => 32
[1] => 4
[2] => 9
[3] => 5
[4] => 10
[5] => 3
)
[4] => Array
(
[0] => 32
[1] => 4
[2] => 9
[3] => 5
[4] => 11
[5] => 3
)
[5] => Array
(
[0] => 32
[1] => 4
[2] => 9
[3] => 5
[4] => 12
[5] => 3
)
)
My problem: I need the array "key" for every horse to be the "race ID", not 0,1,2,3. I need the result to be like this:
Array
(
[0] => Array
(
[4] => 7
[8] => 4
[2] => 9
[12] => 5
[83] => 10
[9] => 3
)
[1] => Array
(
[4] => 7
[8] => 4
[2] => 9
[12] => 5
[83] => 11
[9] => 3
)
[2] => Array
(
[4] => 7
[8] => 4
[2] => 9
[12] => 5
[83] => 12
[9] => 3
)
[3] => Array
(
[4] => 32
[8] => 4
[2] => 9
[12] => 5
[83] => 10
[9] => 3
)
[4] => Array
(
[4] => 32
[8] => 4
[2] => 9
[12] => 5
[83] => 11
[9] => 3
)
[5] => Array
(
[4] => 32
[8] => 4
[2] => 9
[12] => 5
[83] => 12
[9] => 3
)
)
How can I accomplish this? I know its a long post but I needed to graph this. I am having problems to wrap my head around the function recursion and I get totally lost in each loop.
I've got the same problem and Danny's solution wasn't good for me.
I manage thousand of permutation and store them in memory is damn expensive.
Here my solution:
/**
* Calculate permutation of multidimensional array. Without recursion!
* Ex.
* $array = array(
* key => array(value, value),
* key => array(value, value, value),
* key => array(value, value),
* );
*
* #copyright Copyright (c) 2011, Matteo Baggio
* #param array $anArray Multidimensional array
* #param function $isValidCallback User function called to verify the permutation. function($permutationIndex, $permutationArray)
* #return mixed Return valid permutation count in save memory configuration, otherwise it return an Array of all permutations
*/
function permutationOfMultidimensionalArray(array $anArray, $isValidCallback = false) {
// Quick exit
if (empty($anArray))
return 0;
// Amount of possible permutations: count(a[0]) * count(a[1]) * ... * count(a[N])
$permutationCount = 1;
// Store informations about every column of matrix: count and cumulativeCount
$matrixInfo = array();
$cumulativeCount = 1;
foreach($anArray as $aColumn) {
$columnCount = count($aColumn);
$permutationCount *= $columnCount;
// this save a lot of time!
$matrixInfo[] = array(
'count' => $columnCount,
'cumulativeCount' => $cumulativeCount
);
$cumulativeCount *= $columnCount;
}
// Save the array keys
$arrayKeys = array_keys($anArray);
// It needs numeric index to work
$matrix = array_values($anArray);
// Number of column
$columnCount = count($matrix);
// Number of valid permutation
$validPermutationCount = 0;
// Contain all permutations
$permutations = array();
// Iterate through all permutation numbers
for ($currentPermutation = 0; $currentPermutation < $permutationCount; $currentPermutation++) {
for ($currentColumnIndex = 0; $currentColumnIndex < $columnCount; $currentColumnIndex++) {
// Here the magic!
// I = int(P / (Count(c[K-1]) * ... * Count(c[0]))) % Count(c[K])
// where:
// I: the current column index
// P: the current permutation number
// c[]: array of the current column
// K: number of the current column
$index = intval($currentPermutation / $matrixInfo[$currentColumnIndex]['cumulativeCount']) % $matrixInfo[$currentColumnIndex]['count'];
// Save column into current permutation
$permutations[$currentPermutation][$currentColumnIndex] = $matrix[$currentColumnIndex][$index];
}
// Restore array keys
$permutations[$currentPermutation] = array_combine($arrayKeys, $permutations[$currentPermutation]);
// Callback validate
if ($isValidCallback !== false) {
if ($isValidCallback($currentPermutation, $permutations[$currentPermutation]))
$validPermutationCount++;
// *** Uncomment this lines if you want that this function return all
// permutations
//else
// unset($permutations[$currentPermutation]);
}
else {
$validPermutationCount++;
}
// Save memory!!
// Use $isValidCallback to check permutation, store into DB, etc..
// *** Comment this line if you want that function return all
// permutation. Memory warning!!
unset($permutations[$currentPermutation]);
}
if (!empty($permutations))
return $permutations;
else
return $validPermutationCount;
}
//
// How to?
//
$play = array(
'4' => array(7, 32),
'8' => array(4),
'2' => array(9),
'12' => array('5'),
'83' => array('10', '11', '12', ''), // <-- It accept all values, nested array too
'9' => array('3'),
);
$start = microtime(true);
// Anonymous function work with PHP 5.3.0
$validPermutationsCount = permutationOfMultidimensionalArray($play, function($permutationIndex, $permutationArray){
// Here you can validate the permutation, print it, etc...
// Using callback you can save memory and improve performance.
// You don't need to cicle over all permutation after generation.
printf('<p><strong>%d</strong>: %s</p>', $permutationIndex, implode(', ', $permutationArray));
return true; // in this case always true
});
$stop = microtime(true) - $start;
printf('<hr /><p><strong>Performance for %d permutations</strong><br />
Execution time: %f sec<br/>
Memory usage: %d Kb</p>',
$validPermutationsCount,
$stop,
memory_get_peak_usage(true) / 1024);
If someone has a better idea i'm here!
Here's what you need. I have commented as necessary:
function permutations(array $array)
{
switch (count($array)) {
case 1:
// Return the array as-is; returning the first item
// of the array was confusing and unnecessary
return $array;
break;
case 0:
throw new InvalidArgumentException('Requires at least one array');
break;
}
// We 'll need these, as array_shift destroys them
$keys = array_keys($array);
$a = array_shift($array);
$k = array_shift($keys); // Get the key that $a had
$b = permutations($array);
$return = array();
foreach ($a as $v) {
if(is_numeric($v))
{
foreach ($b as $v2) {
// array($k => $v) re-associates $v (each item in $a)
// with the key that $a originally had
// array_combine re-associates each item in $v2 with
// the corresponding key it had in the original array
// Also, using operator+ instead of array_merge
// allows us to not lose the keys once more
$return[] = array($k => $v) + array_combine($keys, $v2);
}
}
}
return $return;
}
See it in action.
By the way, calculating all the permutations recursively is neat, but you might not want to do it in a production environment. You should definitely consider a sanity check that calculates how many permutations there are and doesn't allow processing to continue if they are over some limit, at the very least.
I improved Jon's function by merging his algorithm with the one I had initially. What I did, was check if the function was doing a recursion, if so, I use the original array_merge() (which was working), else I use Jon's array_combine() (to keep the arrays keys).
I'm marking Jon's answer as correct since he proposed a slick solution to keep the array keys intact.
function permutations(array $array, $inb=false)
{
switch (count($array)) {
case 1:
// Return the array as-is; returning the first item
// of the array was confusing and unnecessary
return $array[0];
break;
case 0:
throw new InvalidArgumentException('Requires at least one array');
break;
}
// We 'll need these, as array_shift destroys them
$keys = array_keys($array);
$a = array_shift($array);
$k = array_shift($keys); // Get the key that $a had
$b = permutations($array, 'recursing');
$return = array();
foreach ($a as $v) {
if(is_numeric($v))
{
foreach ($b as $v2) {
// array($k => $v) re-associates $v (each item in $a)
// with the key that $a originally had
// array_combine re-associates each item in $v2 with
// the corresponding key it had in the original array
// Also, using operator+ instead of array_merge
// allows us to not lose the keys once more
if($inb == 'recursing')
$return[] = array_merge(array($v), (array) $v2);
else
$return[] = array($k => $v) + array_combine($keys, $v2);
}
}
}
return $return;
}
Tested successfully with several array combinations.

Categories