Filter array - odd even - php

How can a filter out the array entries with an odd or even index number?
Array
(
[0] => string1
[1] => string2
[2] => string3
[3] => string4
)
Like, i want it remove the [0] and [2] entries from the array.
Or say i have 0,1,2,3,4,5,6,7,8,9 - i would need to remove 0,2,4,6,8.

foreach($arr as $key => $value) if($key&1) unset($arr[$key]);
The above removes odd number positions from the array, to remove even number positions, use the following:
Instead if($key&1) you can use if(!($key&1))

Here's a "hax" solution:
Use array_filter in combination with an "isodd" function.
array_filter seems only to work on values, so you can first array_flip and then use array_filter.
array_flip(array_filter(array_flip($data), create_function('$a','return $a%2;')))

You could also use SPL FilterIterator like this:
class IndexFilter extends FilterIterator {
public function __construct (array $data) {
parent::__construct(new ArrayIterator($data));
}
public function accept () {
# return even keys only
return !($this->key() % 2);
}
}
$arr = array('string1', 'string2', 'string3', 'string4');
$filtered = array();
foreach (new IndexFilter($arr) as $key => $value) {
$filtered[$key] = $value;
}
print_r($filtered);

<?php
function odd($var)
{
// returns whether the input integer is odd
return($var & 1);
}
function even($var)
{
// returns whether the input integer is even
return(!($var & 1));
}
$array1 = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);
$array2 = array(6, 7, 8, 9, 10, 11, 12);
echo "Odd :\n";
print_r(array_filter($array1, "odd"));
echo "Even:\n";
print_r(array_filter($array2, "even"));
?>
Odd :
Array
(
[a] => 1
[c] => 3
[e] => 5
)
Even:
Array
(
[0] => 6
[2] => 8
[4] => 10
[6] => 12
)

I'd do it like this...
for($i = 0; $i < count($array); $i++)
{
if($i % 2) // OR if(!($i % 2))
{
unset($array[$i]);
}
}

<?php
$array = array(0, 3, 5, 7, 20, 10, 99,21, 14, 23, 46);
for ($i = 0; $i < count($array); $i++)
{
if ($array[$i]%2 !=0)
echo $array[$i]."<br>";
}
?>

$array = array(0 => 'string1', 1 => 'string2', 2 => 'string3', 3 => 'string4');
// Removes elements of even-numbered keys
$test1 = array_filter($array, function($key) {
return ($key & 1);
}, ARRAY_FILTER_USE_KEY);
// Removes elements of odd-numbered-keys
$test2 = array_filter($array, function($key) {
return !($key & 1);
}, ARRAY_FILTER_USE_KEY);
This answer is a bit of an improvement over this answer. You can use anonymous functions instead of create_function. Also, array_filter takes an optional flag parameter that lets you specify that the callback function takes the key as its only argument. So you don't need to use array_flip to get an array of keys.

Related

How to not add duplicates to array in O(1) time

I have an INT array. I want to add a number to the array. However, I don't want to add the number if the number already exists. I know I can use array_unique() but the time complexity of that is not O(1). How can I do this in O(1) time complexity. I know I can make the numbers the keys and have empty values and search use isset() to check if the number exists. Is there any other way?
$arr = [1,2,3,4];
$arr = add_to_array($arr, 4); // Should not add arr
$arr = add_to_array($arr, 7); // Should add arr
function add_to_array($arr, $num) {
if(in_array($num, $arr)) {
$arr[] = $num;
}
return $arr;
}
use in_array()==false then add to array as below code
$arr = [1,2,3,4];
$arr = add_to_array($arr, 4); // Should not add arr
$arr = add_to_array($arr, 7); // Should add arr
function add_to_array($arr, $num) {
if(in_array($num, $arr) == false) {
array_push($arr, $num);
}
return $arr;
}
Your output will be :
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 7 )

Filter 2d array to keep all rows which contain a specific value

I have a two dimensional haystack array like this:
[
4 => [0, 1, 2, 3, 10],
1 => [0, 1, 2, 3, 10],
2 => [0, 1, 2, 3],
3 => [0, 1, 2, 3]
]
Let's say that I have a search value of $x = 10.
How can I search in above array and get an array index which contains $x.
In my current example, subarrays with key 4 and 1 contain value of $x -- I need those 2 subarrays.
You could loop then use array_search()
$array = array(...); // Your array
$x = 10;
foreach ($array as $key => $value) {
if (array_search($x, $value)) {
echo 'Found on Index ' . $key . '</br>';
}
}
Or if you need the arrays with those index
$array = array(...); // Your array
$x = 10;
$result = array(); // initialize results
foreach ($array as $key => $value) {
if (array_search($x, $value)) {
$result[] = $array[$key]; // push to result if found
}
}
print_r($result);
You can use array_filter() to keep only the array that contains the value you want:
$array = array(
array(0, 1, 2, 3, 10),
array(0, 1, 2, 3, 10),
array(0, 1, 2, 3),
array(0, 1, 2, 3)
);
$x = 10;
$out = array_filter($array, function($arr) use($x) {
return in_array($x, $arr);
});
print_r($out);
Output:
Array
(
[0] => Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
[4] => 10
)
[1] => Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
[4] => 10
)
)
You can use as well in_array
$array = array(); // Your array
$x = 10;
$result = array(); // initialize results
foreach ($array as $key => $value) {
if (in_array($x, $value)) {
$result[] = $array[$key]; //
}
}
print_r($result)
You can use array_search() function to search the value in array..
Link: http://php.net/manual/en/function.array-search.php
For Exp:
$x = 10; // search value
$array = array(...); // Your array
$result = array(); // Result array
foreach ($array as $key => $value)
{
if (array_search($x, $value))
{
$result[] = $array[$key]; // push the matched data into result array..
}
}
print_r($result);
You can use array_search();
doc: http://www.php.net/manual/en/function.array-search.php

Find combination of array keys with values

In order to optimize the output I recently ran into a situation where I have to get the all the combinations of array keys inside an array. I looked into several places (including StackOverflow) but could not find the solution since most are related to permutation rather than combination.
Given this input
$input = ['jack' => 11, 'moe' => 12, 'shane' => 12];
Output should be something like this (the order inside an array does not matter).
$output = [
['jack' => 11],
['jack' => 11, 'moe' => 12]
['jack' => 11, 'moe' => 12, 'shane' => 12]
['moe' => 12],
['moe' => 12, 'shane' => 12]
['shane' => 12],
['shane' => 12, 'jack' => 11]
];
I tried this but after third iteration it does not work.
function combination(array $inputs, array $temp, &$collect) {
if (!empty($temp)) {
$collect[] = $temp;
}
for ($i = 0; $i < sizeof($inputs); $i++) {
$inputCopy = $inputs;
$elem = array_splice($inputCopy, $i, 1);
if (count($inputCopy) > 0) {
$temp[array_keys($elem)[0]] = array_values($elem)[0];
combination($inputCopy, $temp, $collect);
} else {
$temp[array_keys($elem)[0]] = array_values($elem)[0];
$collect[] = $temp;
$temp = [];
}
$i++;
}
}
Though I need this in PHP even Python (without using itertools combination), Java, Javascript will work for me.
I have found a way of doing what you want, but definitely, this is not a "fancy" solution. I would suggest you to work a little bit with it to find something better, but at least this gives you the result.
Here you go :
<?php
$baseArray = [
"joe" => 11,
"molly" => 12,
"sam" => 13,
];
function getAllPermutations($array = []) {
if (empty($array)) {
return [];
}
$result = [];
foreach ($array as $key => $value) {
unset($array[$key]);
$subPermutations = getAllPermutations($array);
$result[] = [$key => $value];
foreach ($subPermutations as $sub) {
$result[] = array_merge([$key => $value] , $sub);
}
}
return $result;
}
print_r(getAllPermutations($baseArray));
Output being :
Array
(
[0] => Array
(
[joe] => 11
)
[1] => Array
(
[joe] => 11
[molly] => 12
)
[2] => Array
(
[joe] => 11
[molly] => 12
[sam] => 13
)
[3] => Array
(
[joe] => 11
[sam] => 13
)
[4] => Array
(
[molly] => 12
)
[5] => Array
(
[molly] => 12
[sam] => 13
)
[6] => Array
(
[sam] => 13
)
) }
Hope this helped.
You read about really clever non-recursive algorithm here: PHP: Find every combination of an Array. You can adopt it (mostly copy and paste) to write generator function:
function keyCombinations($array)
{
$keys = array_keys($array);
$num = count($keys);
$total = pow(2, $num);
for ($i = 1; $i < $total; $i++) {
$combination = [];
for ($j = 0; $j < $num; $j++) {
if (pow(2, $j) & $i) {
$key = $keys[$j];
$combination[$key] = $array[$key];
}
}
yield $combination;
}
}
One important point here. In the original article $i initialized with 0, we initialize it with 1 to exclude empty array from the result.
Having this function you can get all combinations:
foreach (keyCombinations($input) as $combination) {
print_r($combination);
}
Here is working demo.
If, in your final combination, you include the empty set, your problem is equivalent to enumerating a binary number of "n" bits. Where "n" is the number of elements in your set.
You need a recursive algorithm like this one:
def comb(initialSet, results=[], currentIndex=0, currentResult=[]):
if currentIndex >= len(initialSet):
results.append( currentResult[:] )
else:
currentResult.append( initialSet[currentIndex] )
comb(initialSet, results, currentIndex + 1, currentResult)
currentResult.pop()
comb(initialSet, results, currentIndex + 1, currentResult)
return results

PHP - Use multiple values in foreach loop

I have the two PHP loops as below:
foreach ($directData as $key => $val) {
echo $val;
echo "|"; //Just for the visual.
}
foreach ($sdata as $key => $val) {
echo $val;
echo "|"; //Just for the visual.
}
Which output:
5|5|5|10|10|10|0| and the second: 2|2|2|5|5|5|20|
My question is, how can I combine these two result (add them) and print it out like above?
So, it would be:
7|7|7|15|15|15|20
php > $a = [1, 2, 3];
php > $b = [4, 5, 6];
php > $c = array_map(function($x, $y){ return $x + $y; }, $a, $b);
php > print_r($c);
Array
(
[0] => 5
[1] => 7
[2] => 9
)
php > print_r(implode($c, '|') . '|');
5|7|9|
Broken down for better readability, this will sum them into $new array.
array_map will iterate through both given arrays and apply the callback function to both of the arrays at their current indexes. The callback function will sum the values of at current indexes.
$new=array_map(
function(){
return array_sum(func_get_args());
},
$directData, $sdata
);
$out= '';
foreach ($new as $key => $val)
$out .= $val.'|';
echo rtrim($out,'|');
in simple way you can do it like:
$finalData = array_map(function () {
return array_sum(func_get_args());
}, $directData, $sdata );
print_r($finalData );
If each index corresponds in the arrays
$rezult = array();
for($i=0;$i<count($directData);$i++){
$rezult[] = $directData[$i] + $sdata[$i];
}
echo join("|",$rezult);
Here is a method that uses the iterators that all PHP arrays have.
/**
* Use the iterator that all PHP arrays have.
*
* Check both arrays for having entries.
*/
$listOut = array(); // output in here
while (current($listA) !== false && current($listB) !== false) {
$listOut[] = current($listA) + current($listB);
next($listA);
next($listB);
}
Input:
$listA = array(5, 5, 5, 10, 10, 10, 0);
$listB = array(2, 2, 2, 5, 5, 5, 20, );
Output
Array
(
[0] => 7
[1] => 7
[2] => 7
[3] => 15
[4] => 15
[5] => 15
[6] => 20
)
7| 7| 7| 15| 15| 15| 20

PHP Search array recursively and return count of index?

Is there a PHP function that lets you search an array recursively and return the number of instances a certain key 'x' occurs (regardless of how deep)?
I would use array_walk_recursive(). Example:
$a = array(1,2,3,'x',array(4,5,'x',array(6,7,8,'x')));
$v = "x";
$i = 0;
array_walk_recursive($a, function($val, $key) use (&$i, $v) {
if ($val == $v) {
$i++;
}
});
echo $i;
Output:
3
You can traverse the array recursively (that is regardless of the depth) and then count the values:
$array = array(1, 2, 3, 'x', array(4, 5, 'x', array(6, 7, 8, 'x')));
$rit = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
$xCount = 0;
foreach ($rit as $value) {
if ($value === 'x') {
$xCount++;
}
}
var_dump($xCount); # int(3)
A variation of this is to convert this iteration into an array again and count values:
$array = array(1, 2, 3, 'x', array(4, 5, 'x', array(6, 7, 8, 'x')));
$rit = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
$allCount = array_count_values(iterator_to_array($rit, FALSE));
print_r($allCount);
Output/Result:
Array
(
[1] => 1
[2] => 1
[3] => 1
[x] => 3
[4] => 1
[5] => 1
[6] => 1
[7] => 1
[8] => 1
)
See as well:
How do I use a recursive array iterator to process a multidimensional array?
You could write a simple recursive function that does what you want. I didn't test this, but the idea would be something like:
$count = 0;
function findKey($array,&$count){
if(!empty($array)){
foreach($array as $key => $childArray){
if($key == 'keyImLookingFor'){
$count++;
}
findKey($childArray,$count);
}
}
}
$count should then contain your number of key occurrences. Again, this might need some cleanup.
$array = array(
'key1' => 'val1',
'key2' => 'val2',
'key3' => array('key1' => 'val3'));
$count = 0;
function key_count($val, $key){
global $count;
if($key == "key1"){
$count++;
}
}
array_walk_recursive($array, 'key_count');
echo $count;

Categories