Array_Search For Multiple Same Elements [duplicate] - php

This question already has answers here:
How to search Array for multiple values in PHP?
(6 answers)
Closed 2 years ago.
there is an array like $arr = array(1,2,3,3,3,4,5) . What if we want to get all indexes that have values 3?
i used array_search(3, $arr) but it just give back an integer and just the first index that has value '3'
how can we get an array like $indexes = array(2,3,4) that shows all indexes that have value 3?
your help will be highly appreciated

You can use array_keys with search value PHP Doc
Demo
array_keys($arr,3)
array_keys() returns the keys, numeric and string, from the array.
If a search_value is specified, then only the keys for that value are
returned. Otherwise, all the keys from the array are returned.

you can use array_keys:
foreach (array_keys($arr) as $key) if ($arr[$key] == 3) $result[] = $key;

With that solution you can create complex filters. In this case we compare every value to be the number three (=== operator). The filter returns the index, when the comparision true, else it will be dropped.
$a = [1,2,3,4,3,3,5,6];
$threes = array_filter($a, function($v, $k) {
return $v === 3 ? $k : false; },
ARRAY_FILTER_USE_BOTH
);
$threes Is an array containing all keys having the value 3.
array(3) { 2, 4, 5 }

Related

Get an array column based on the values of another column in PHP [duplicate]

This question already has answers here:
How to filter an array by a condition
(9 answers)
get specific column with specific condition from multidimensional array using array function only in php
(4 answers)
Closed 3 years ago.
I have a multi-column PHP array as
Array (
Array ('col1', 'col2', 'col3'),
);
How can I get an array of col2 if col1 is greater than a specific value?
I can do it by a foreach loop, but I think it should be possible with a native function like array_filter.
Simply put, you're better with a foreach loop, as you're not going to have to make multiple iterations of the array. You want to both filter and modify the array, which requires using both array_filter() and array_map() in order to get what you want:
<?php
$arr = [
[5, 'col2-1', 'col3'],
[10, 'col2-2', 'col3']
];
$res = array_filter($arr, function($item) {
return $item[0] > 7;
});
$res = array_map(function($item) {
return $item[1];
}, $res);
var_dump($res);
Test here: https://3v4l.org/HRTOJ

How to allow same keys in one array? [duplicate]

This question already has answers here:
PHP Associative Array Duplicate Keys
(6 answers)
Closed 4 years ago.
I need to add the same keys to the array, but with different values,
foreach ($selections as $selection) {
$array += [$selection['option_id']=>$selection['product_id']];
}
// example output
$array = [30=>12,14=>10],
but really it should be
[30=>7,30=>12,14=>10];
When the key repeats, it merges.
You just can't.
But you can make the value of this key an array.
So you'll have
$array = [30=>[7,12],14=>10];
You can use any array functions on $array[30]
What you should do is to return the products ids as an array:
$array = array_reduce($selections, function ($carry, $selection) {
if (!isset($carry[$selection['option_id']])) {
$carry[$selection['option_id']] = [];
}
$carry[$selection['option_id']][] = $selection['product_id'];
return $carry;
}, []);
Now the result would be:
[30 => [7, 12], 14 => [10]];
Keys in array are, as the word itself says, keys to access the value they contain and each key must be unique, else you won't have a way to . If you could have two time or more the same value, how could you tell which will access one value and which one will access the other one? To solve your problem you have a way: generate a multidimensional array such that you can have multiple value stored "behind" a single key. E.g. [30 => [7,12], 14 => 10]
Based on your code you can just create a double loop with a nested foreach to navigate through all the value, something like:
foreach ($selections as $selection) {
if(!is_array($selection['product_id']) $array += [$selection['option_id']=>$selection['product_id']];
else {
foreach ($selection['product_id'] as $product) {
$array += [$selection['option_id']=> product];
}
}
}

PHP combine arrays with logical operator

Is there a way to combine boolean arrays:
$array1: ['prop1'=>T, 'prop2'=>F, 'prop3'=>T, 'prop4'=>F, 'prop5'=>T]
$array2: ['prop1'=>T, 'prop2'=>F, 'prop3'=>F, 'prop4'=>T]
Into
$array3: ['prop1'=>T, 'prop2'=>F, 'prop3'=>T, 'prop4'=>T, 'prop5'=>T]
Using the OR comparison?
I thought using $array3 = $array1 | $array2 would work but it returns a single value.
I feel like this could be a duplicate but I failed to find the same question on SO.
While each array have the same key you can use foreach loop to loop through the first array check if equally then you set the key and value to result array else if not equally then use the one with true value
$result=array();
foreach($array1 as $key=>$value){
if($array1[$key]==$array2[$key] || $array2==undefined){
$result[$key]=$value;
}
else{
$result[$key]=($array1[$key]==True)?$array1[$key] : $array2[$key];
}
}
Then loop through second array to see if the key is undefined in first to add the key value from second array
foreach($array2 as $key=>$value){
if ($array1[$key]==undefined){
$result[$key]=$value;
}
}
This is the shortest solution I can think of. And it's really not that complicated :). First we add the two arrays to make sure all keys exist in $result. Then we use the array_walk to perform the logical operation.
We need 3 arguments. The first is the $result variable we want to manipulate.
The third argument gets passed to our callback. We again use an array sum to ensure all keys are set, but this time $array2 gets the precedence.
The second is our callback. We get each value from the preliminary result by reference (&), each key by value, and our wish as a third parameter. The function itself is really simple we just set $v to whatever operation we want to implement. || for OR, && for AND or xor for XOR (but xor needs additional parentheses, see Operator precedence).
Demo
$array1 = ['prop1'=>TRUE, 'prop2'=>FALSE, 'prop3'=>TRUE, 'prop4'=>TRUE];
$array2 = ['prop1'=>TRUE, 'prop2'=>TRUE, 'prop3'=>FALSE, 'prop5'=>FALSE];
$result = $array1 + $array2;
array_walk($result, function(&$v, $k, $a){
$v = $v || $a[$k]; //Here you can change the operation
}, $array2+$array1);
var_dump($result);

Sort array by values ASC, then keys ASC [duplicate]

This question already has answers here:
Sort a flat, associative array by numeric values, then by non-numeric keys
(8 answers)
Closed 6 months ago.
SO,
The problem
I have an issue with custom array sorting. I have an array:
$rgData = [
3 => 1,
5 => 0,
1 => 2,
9 => 0,
0 => 1,
4 => 2,
2 => 1,
7 => 0,
6 => 0,
8 => 0,
];
-it contain keys with their counts (actually, it came after some operations with array_count_values). Now I want to sort it that:
Lower values comes first (i.e. usual ascending sort which can be done with asort())
Within one value, keys should be sorted ascending (here I need help)
For sample above result should be:
[5=>0, 6=>0, 7=>0, 8=>0, 9=>0, 0=>1, 2=>1, 3=>1, 1=>2, 4=>2]
My approach
I have no idea how to resolve this with sort by user-defined since usort or uasort accept only values for comparing while uksort - only keys and I need both of them in my comparison function. The only way that I have now - is to do this:
$rgData = ['3'=>1, '5'=>0, '1'=>2, '9'=>0, '0'=>1, '4'=>2, '2'=>1, '7'=>0, '6'=>0, '8'=>0];
$rgTemp = [];
asort($rgData);
$i = 0;
$mPrev = current($rgData);
foreach($rgData as $mKey=>$mValue)
{
$rgTemp[$mPrev==$mValue?$i:++$i][$mKey] = $mValue;
$mPrev = $mValue;
}
$rgTemp = array_map(function($rgX)
{
ksort($rgX);
return $rgX;
}, $rgTemp);
$rgData = [];
//can't use call_user_func_array('array_merge', $rgTemp) - it spoils numeric keys
foreach($rgTemp as $rgX)
{
foreach($rgX as $mKey=>$mValue)
{
$rgData[$mKey] = $mValue;
}
}
//var_dump($rgData);
-i.e. split array by values first, then do the stuff.
The question
How to do this in more easy way? I used asort + cycled ksort via array_map with final gathering loop. Temp array also used. It looks weird. I hope simpler method exists.
This should do what you want. It sorts by the keys, but we can access the value inside the function, so we can use that as our sort criteria too.
uksort($rgData, function($a, $b) use($rgData){
$aVal = $rgData[$a];
$bVal = $rgData[$b];
// Compare the values
if($aVal === $bVal){
// If they are the same, compare the keys
return $a - $b;
}
// Otherwise compare the values
return $aVal - $bVal;
});

Array_merge versus + [duplicate]

This question already has answers here:
What's the difference between array_merge and array + array? [duplicate]
(9 answers)
Closed 7 years ago.
When I use array_merge() with associative arrays I get what I want, but when I use them with numerical key arrays the keys get changed.
With + the keys are preserved but it doesn't work with associative arrays.
I don't understand how this works, can anybody explain it to me?
Because both arrays are numerically-indexed, only the values in the first array will be used.
The + operator returns the right-hand array appended to the left-hand array; for keys that exist in both arrays, the elements from the left-hand array will be used, and the matching elements from the right-hand array will be ignored.
http://php.net/manual/en/language.operators.array.php
array_merge() has slightly different behavior:
If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended. Values in the input array with numeric keys will be renumbered with incrementing keys starting from zero in the result array.
http://php.net/manual/en/function.array-merge.php
These two operation are totally different.
array plus
Array plus operation treats all array as assoc array.
When key conflict during plus, left(previous) value will be kept
null + array() will raise fatal error
array_merge()
array_merge() works different with index-array and assoc-array.
If both parameters are index-array, array_merge() concat index-array values.
If not, the index-array will to convert to values array, and then convert to assoc array.
Now it got two assoc array and merge them together, when key conflict, right(last) value will be kept.
array_merge(null, array()) returns array() and got a warning said, parameter #1 is not an array.
I post the code below to make things clear.
function array_plus($a, $b){
$results = array();
foreach($a as $k=>$v) if(!isset($results[$k]))$results[$k] = $v;
foreach($b as $k=>$v) if(!isset($results[$k]))$results[$k] = $v;
return $results;
}
//----------------------------------------------------------------
function is_index($a){
$keys = array_keys($a);
foreach($keys as $key) {
$i = intval($key);
if("$key"!="$i") return false;
}
return true;
}
function array_merge($a, $b){
if(is_index($a)) $a = array_values($a);
if(is_index($b)) $b = array_values($b);
$results = array();
if(is_index($a) and is_index($b)){
foreach($a as $v) $results[] = $v;
foreach($b as $v) $results[] = $v;
}
else{
foreach($a as $k=>$v) $results[$k] = $v;
foreach($b as $k=>$v) $results[$k] = $v;
}
return $results;
}

Categories