Remove random items from PHP array - php

I need to reduce the size of this array to X, so i would like to remove X random items. Here's my PHP array:
Array
(
[helping] => 3
[me] => 2
[stay] => 1
[organized!] => 1
[votre] => 4
[passion,] => 1
[action,] => 1
[et] => 2
[impact!] => 1
[being] => 4
)
I tried array_rand() but it didn't keep the keys/values.

array_rand() returns a random key (or more) of the given array, unset using that:
$randomKey = array_rand($array, 1);
unset($array[$randomKey]);

array_rand() returns an array with keys from your original array.
You would need to delete the keys from your original array using a foreach-loop.
Like this:
// Suppose you need to delete 4 items.
$keys = array_rand($array, 4);
// Loop through the generated keys
foreach ($keys as $key) {
unset($array[$key]);
}

$foo = Array(
"helping" => 3,
"me" => 2,
"stay" => 1,
"organized!" => 1,
"votre" => 4,
"passion," => 1,
"action," => 1,
"et" => 2,
"impact!" => 1,
"being" => 4
);
$max = 5; //number of elements you wish to remain
for($i=0;$i<$max;$i++){ //looping through $max iterations, removing an element at random
$rKey = array_rand($foo, 1);
unset($foo[$rKey]);
}
die(print_r($foo));

Use this,
$array = array(); // Your array
$max = 3;
$keys = array_rand($array, count($array) - $max);
// Loop through the generated keys
foreach ($keys as $key) {
unset($array[$key]);
}

If you need to remove an unknown item number, you can do :
$myArr = [
'helping' => 3,
'me' => 2,
'stay' => 1,
'organized!' => 1,
'votre' => 4,
'passion,' => 1,
'action,' => 1,
'et' => 2,
'impact!' => 1,
'being' => 4,
];
$countToRemove = random_int(1, 2); // can return 1 or 2
$keysToRemove = array_rand($myArr, $countToRemove); // returns an int or array
// create the array to loop
foreach (\is_array($keysToRemove) ? $keysToRemove : [$keysToRemove] as $key) {
unset($myArr[$key]);
}
var_dump($myArr); die();
In this case it will randomly remove 1 or 2 items from the array.

Related

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

Count duplicate numbers inside of foreach

Basically, I am fetching data from an API and that API has duplicate numbers. I want to count the duplicate numbers within the foreach, but its not working for some reason. I am not sure what I am doing wrong. You can see there is 33 many times. See the picture how it prints. It should be showing something like this
Array
(
[33] => 5
[2] => 3
)
Code:
foreach ($parsed_json1->numbers as $item) {
$ui = $item->no;
$currentp= number_format($ui, 6);
//echo $currentp;
//echo "</br>";
$array = array($currentp);
$vals = array_count_values($array);
//echo 'No. of NON Duplicate Items: '.count($vals).'<br><br>';
print_r($vals);
}
The fundamental flaw of your code is that you take one value and format it, then you put it into array and then do array_count_values on it.
See the difference:
$arr = [33, 32, 23, 33, 22, 23, 32, 33, 33];
print_r(array_count_values($arr));
foreach($arr as $a) {
$currentp= number_format($a, 6);
$array = array($currentp);
$vals = array_count_values($array);
print_r($vals);
}
First print_r prints:
Array
(
[33] => 4
[32] => 2
[23] => 2
[22] => 1
)
And the print_r inside foreach prints:
Array([33.000000] => 1)
Array([32.000000] => 1)
Array([23.000000] => 1)
Array([33.000000] => 1)
Array([22.000000] => 1)
Array([23.000000] => 1)
Array([32.000000] => 1)
Array([33.000000] => 1)
Array([33.000000] => 1)
Do you realize the difference?
I guess, what you need is
$arr = (array_count_values([33, 32, 23, 33, 22, 23, 32, 33, 33]));
$new_arr = [];
foreach($arr as $k => $a) {
$new_arr[number_format($k, 6)] = $a;
}
print_r($new_arr);
Which outputs:
Array
(
[33.000000] => 4
[32.000000] => 2
[23.000000] => 2
[22.000000] => 1
)
Not sure why you use number_format(), but I'm guessing you need something like this
$num_array = []; // Initialize number array
foreach ($parsed_json1->numbers as $item) {
$ui = $item->no;
$currentp= number_format($ui, 6);
$num_array[] = $currentp; // Store each number first to number array
}
// After foreach loop, do array_count_values to number array
$vals = array_count_values($num_array);
print_r($vals); //Print result

Randomly select words from multi-dimension array

I have a multi-dimensional array and from where i want to choose 11 different words. Each word from different array index.
Here is the array link: My multi-dimensional array
array (
'w' =>
array (
0 => 'walls',
1 => 'well',
2 => 'why',
),
'e' =>
array (
0 => 'end',
),
'a' =>
array (
0 => 'advantage',
1 => 'afford',
2 => 'affronting',
3 => 'again',
4 => 'agreeable',
5 => 'ask',
6 => 'at',
),
'c' =>
array (
0 => 'children',
1 => 'civil',
2 => 'continual',
)
);
My Desire Output:
From w => well
From e => end
From a => again
and so on.
Output like: array(well, end, again, ...) as array.
Use the following code:
$f = array_keys($result); // grouping the indices, namely, the characters
$a = "";
for($c=0;$c<count($f);$c++){
$a .= $f[$c];
} // grouping the indices stored in array $f to a string, $a
$words = array();
for($c=0;$c<11;$c++){
$random = $a[rand(0,strlen($a)-1)];
$k = $result[$random];
// $k stores the array of the character index, stored in $result
$random2 = rand(0,count($k)-1);
$words[$c] = $k[$random2];
// choose a word from a given character array
$a = preg_replace("/".$random."/","",$a);
// remove the character from $a to prevent picking words which start with the same character
}
print_r($words);
I've tested and it was proved working
https://3v4l.org/qi1VP
You can achieve this usin array_rand() function :
PHP
$words = [];
$limit = 3; //Replace this with your limit, 11
$count = 0;
shuffle($array);
foreach($array as $key => $value) {
$words[] = $value[array_rand($value)];
$count++;
if ($limit == $count) {
break;
}
}
EvalIn
Check Online, and let me know.
using shuffle and array_slice you can get what you want.
A shuffle function makes your array random, and array slice slice 11 sub array from it.
Array slice takes 3 argument, first one is the array, second one is the offset from where you want to start and last one how much you need to cut.
$words = array();
shuffle($result);
$res = array_slice($result, 0, 11);
foreach($res as $key => $value){
shuffle($value);
$words[] = $value[0];
}
print_r($words);

Remove every nth item from array

I want to unset every second item from an array. I don't care about if the keys are reordered or not.
Of course I want it fast and elegant. Is it maybe possible without a loop and temporary variables?
My own solution so far:
for ( $i = 1; isset($arr[$i]); $i += 2) {
unset($arr[$i]);
}
The pro is, that it needs no if-statement, the con that a variable ($i) is still needed and it works only if the keys are numeric and without gaps.
function arr_unset_sec(&$arr, $key)
{
if($key%2 == 0)
{
unset($arr[$key]);
}
}
array_walk($arr, 'arr_unset_sec');
Assuming $arr may be some array. Check this piece of code.
If you have an array like
Array
(
[0] => test1
[1] => test2
[2] => test3
[3] => test4
[4] => test5
)
Then you can go with below code. It will remove every second item of array.
$i = 1;
foreach ($demo_array as $key => $row) {
if($i%2 == '0')
{
unset($demo_array[$key]);
}
$i++;
}
Hope this will helps you. Let mee know if you need any further help on it.
Another solution without a loop:
$arr = array('a', 'b', 'c', 'd', 'e');
$arr = array_filter( $arr, function($k) { return $k % 3 === 0; }, ARRAY_FILTER_USE_KEY);
Pro, it needs no loop. Cons, it is a lot slower than my other version (with a for loop), looks a bit scary and depends again on the keys.
I'll provide two methods (array_filter() and a foreach() loop) which will leverage the condition $i++%$n to target the elements to be removed.
Both methods will work on indexed and associative arrays.
$i++ This is post-incrementation. Effectively, the value will be evaluated first, then incremented second.
% This is the modulo operator - it returns the "remainder" from the division of the leftside value from the rightside value.
The return value from the condition will either be 0 or a positive integer. For this reason, php's inherent "type juggling" feature can be used to convert 0 to false and positive integers as true.
In the array_filter() method, the use() syntax must use &$i so that the variable is "modifiable". Without the &, $i will remain static (unaffected by post-incrementation).
In the foreach() method, The condition is inverted !() in comparison to the array_filter() method. array_filter() wants to know what to "keep"; foreach() wants to know what to unset().
Code: (Demo)
// if:$n=2 $n=3 $n=4 $n=5
$array=['first'=>1,
2, // remove
'third'=>3, // remove
'fourth'=>4, // remove remove
5, // remove
6, // remove remove
'seventh'=>7,
'eighth'=>8, // remove remove
'ninth'=>9]; // remove
// if $n is 0 then don't call anything, because you aren't attempting to remove anything
// if $n is 1 then you are attempting to remove every element, just re-declare as $array=[]
for($n=2; $n<5; ++$n){
$i=1; // set counter
echo "Results when filtering every $n elements: ";
var_export(array_filter($array,function()use($n,&$i){return $i++%$n;}));
echo "\n---\n";
}
echo "\n\n";
// Using a foreach loop will be technically faster (only by a small margin) but less intuitive compared to
// the literal/immediate interpretation of "array_filter".
for($n=2; $n<5; ++$n){
$i=1;
$copy=$array;
foreach($copy as $k=>$v){
if(!($i++%$n)) unset($copy[$k]); // or $i++%$n==0 or $i++%$n<1
}
echo "Results when unsetting every $n elements: ";
var_export($copy);
echo "\n---\n";
}
Output:
Results when filtering every 2 elements: array (
'first' => 1,
'third' => 3,
1 => 5,
'seventh' => 7,
'ninth' => 9,
)
---
Results when filtering every 3 elements: array (
'first' => 1,
0 => 2,
'fourth' => 4,
1 => 5,
'seventh' => 7,
'eighth' => 8,
)
---
Results when filtering every 4 elements: array (
'first' => 1,
0 => 2,
'third' => 3,
1 => 5,
2 => 6,
'seventh' => 7,
'ninth' => 9,
)
---
Results when unsetting every 2 elements: array (
'first' => 1,
'third' => 3,
1 => 5,
'seventh' => 7,
'ninth' => 9,
)
---
Results when unsetting every 3 elements: array (
'first' => 1,
0 => 2,
'fourth' => 4,
1 => 5,
'seventh' => 7,
'eighth' => 8,
)
---
Results when unsetting every 4 elements: array (
'first' => 1,
0 => 2,
'third' => 3,
1 => 5,
2 => 6,
'seventh' => 7,
'ninth' => 9,
)
---
$n = 1
for( $i=$n;$i=$n;)
{
unset($arOne[$i]);
unset($arSnd[$i]);
unset($arThd[$i]);
break;
}
I think this will also perfectly.

Get elements of associated array based on values

I have this array:
Array ( 'jan' => 2, 'feb' => 1, 'mar' => 2, 'apr' => 1 )
..and I want to return:
Array ('jan', 'mar')
As in, find the 2 elements with the highest count and put them in an array. What is the simplest way to achieve this?
You can use max() to get the maximum value, and array_keys() to get an array containing the keys that had that value.
$max = array_keys($array, max($array));
Well, this one works when you need to get fixed number of top values.
$array = array( 'jan' => 2 'feb' => 1 'mar' => 2 'apr' => 1 );
arsort($array);
$i = 0;
$max = 2;
$newArray = Array();
foreach($array as $key => $value)
{
if ($i < $max)
{
$newArray[] = $key;
}
$i++;
}

Categories