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
)
)
Related
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
I want to count how many times a number exists in my array, but I want to do it like this.
I have an empty array like this:
$aNumberArray = array();
And I have an array like this:
$aArray = (4,4,5,7,4,8,7,9,4,3);
This is my code so far:
foreach ($aArray as $value) {
if (in_array($value, $aNumberArray)) {
// increase value in $aNumerArray.
}else{
// add $value from $aArray to $aNumberArray as key and as value add 1.
}
}
I want to know how I can add the value from $aArray to $aNumberArray as a key and I want to add number 1 as value. When It excist it most increase the value from $aArray.
Here you go:
<?php
$aNumberArray = array();
$aArray = array(4,4,5,7,4,8,7,9,4,3);
foreach ($aArray as $value) {
if (!isset($aNumberArray[$value])) {
$aNumberArray[$value] = 0;
}
$aNumberArray[$value] += 1;
}
print_r($aNumberArray);
Will give you:
Array
(
[4] => 4
[5] => 1
[7] => 2
[8] => 1
[9] => 1
[3] => 1
)
Check output of it
$aArray = [4,4,5,7,4,8,7,9,4,3]; // correct this array format
print_r(array_count_values($aArray));
Output
Array
(
[4] => 4
[5] => 1
[7] => 2
[8] => 1
[9] => 1
[3] => 1
)
Demo
array_count_values — Counts all the values of an array
I have this array. I want to duplicate all records form an array. I tried array_unique but it's removing duplicate but doesn't remove orignal value.
Array (
[0] => 1
[1] => 2
[2] => 3
[3] => 1
[4] => 6
[5] => 1
[6] => 23
[7] => 2
)
I want to remove all duplicate value like 1 and 2 and I want this output :
Array
(
[0] => 3
[1] => 6
[2] => 23
)
You could use a combination of array_filter and array_count_values.
$values = [1,2,3,1,6,1,23,2];
$result = array_filter(array_count_values($values), function($x) {
return $x === 1;
});
print_r(array_keys($result));
Result:
Array
(
[0] => 3
[1] => 6
[2] => 23
)
You can also use array_intersect with array_count_values.
Array_intersect returns values that is 1, and array_keys returns the keys (values).
$values = [1,2,3,1,6,1,23,2];
$result = array_keys(array_intersect(array_count_values($values), [1]));
var_dump($result); //[3,6,23]
https://3v4l.org/cHU5E
Another option is to use array_unique and the use array_diff_assoc() to get a list of what has been removed.
Using that array list in array_diff results in the values that is not duplicated.
$values = [1,2,3,1,6,1,23,2];
$diff = array_diff_assoc($values, array_unique($values));
$result = array_diff($values, $diff);
var_dump($result); //[3,6,23]
https://3v4l.org/XM5sk
This question already has answers here:
Transpose 2d array, join second level with commas, and join first level with pipes
(5 answers)
Closed 7 months ago.
I have an array with arrays in it representing values in a database.
There are over 100 columns in the db table so the actual count is much higher than this example below of 6 values, the sub-array (Array within the array) index 0-5.
The columns are in each index of the sub-array and the rows are in each index of the main array.
Here is my main array with sub-arrays:
Array
(
[0] => Array
(
[0] => N
[1] => N
[2] => Y
[3] => Y
[4] => Y
[5] => Y
)
[1] => Array
(
[0] => N
[1] => N
[2] => Y
[3] => Y
[4] => N
[5] => Y
)
[2] => Array
(
[0] => N
[1] => N
[2] => Y
[3] => Y
[4] => N
[5] => Y
)
[3] => Array
(
[0] => Y
[1] => Y
[2] => Y
[3] => Y
[4] => Y
[5] => Y
)
What I need to do is concat all the values of each sub index into one array like this:
Array
(
[0] => N,N,N,Y
[1] => N,N,N,Y
[2] => Y,Y,Y,Y
[3] => Y,Y,Y,Y
[4] => Y,N,N,Y
[5] => Y,Y,Y,Y
)
There will always be the same number of columns (sub index) but there will be different amounts of rows (index).
The idea is get the data by column, you're in luck, there's a built in function for that. Its array_column.
So first, get the number of columns and simply use a for loop for that. Then just use implode and assign it inside a new container:
$new = array(); // container
$count = count($arr[0]); // get the number of colums
for ($i = 0; $i < $count; $i++) {
// get the data by column number ($i), then implode and push inside
$new[] = implode(',', array_column($arr, $i));
}
Here's a sample output
Avoid using explicit loops like for and while. Use array_map (it can take the variable mumber of arrays to traverse):
$result = array_map(function (...$column) {
return implode(',', $column);
}, ...$array);
Here is the demo.
By the way, in linear algebra this is called transpose of the matrix.
From PHP7.4 and higher, the same technique can be written as: (Demo)
var_export(
array_map(
fn() => implode(',', func_get_args()),
...$array
)
);
Or: (Demo)
var_export(
array_map(
fn(...$column) => implode(',', $column),
...$array
)
);
I assume that you have defined $column as the total number of column in your db table. Use array_column to get the value according to the column key.
$result = array();
for ($i = 0; $i < $column; $i++) {
$res = array_column($arr, $i);
$result[] = implode(",", $res);
}
For more information about array_column function, check this link.
Oh, just to let you know that array_column function only works for PHP 5.5 and higher.
check if this is what you want
$arr = array(//your array);
$newArr = array(); //data wil lbe saved here
foreach($arr as $arr_one){
$string = "";
foreach($arr_one as $subArr){
$string.=$subArr.",";
}
array_push($newArr,rtrim($string,','));
}
var_dump($newArr);
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.