I am working on a small php script, currently i have an array like this
[0] yassine#m, [1] yassine#f, [2] Dolmi#m , [3] yassine#l
I want PHP to check if there is a duplicated element (yassine in this case) and return something like this.
[0] yassine , [1] Dolmi#m
array_unique won't work. And i really don't have any clue how to solve this. If looked for a solution on the internet but doesnt seem to find it. Anyone can help Please ?
I think this may work for you.
First sort array by value, then use combination of substr(), strpos() and array_push() to create new array according to your need
then remove duplicate value using array_unique()
<?php
$oldarray = array("suman#1","suman#2","suman#3","sujan#1","suresh#2","");
// first sort array by value so matching value comes together
asort($oldarray);
$newarray = array();
$count = count($oldarray);
for($i=0; $i < $count-1; $i++){
$a = $oldarray[$i];
$b = $oldarray[$i+1];
if($i == 0)
$c = "";
else
$c = $oldarray[$i-1];
if(substr($a,0,strpos($a,"#")) == substr($b,0,strpos($b,"#")) || substr($a,0,strpos($a,"#")) == substr($c,0,strpos($c,"#")) ){
array_push($newarray,substr($a,0,strpos($a,"#")));
}
else
array_push($newarray,$a);
}
print_r($oldarray);
// now remove duplicate value from new array
$newarray = array_unique($newarray);
print_r($newarray);
?>
Check following solution
http://ideone.com/fork/kJlLbs
<?php
function generateUniqueList ($arr){
$ret = array();
foreach ($arr as $value) {
$key = explode("#", $value)[0];
if (array_key_exists($key, $ret)) {
$ret[$key] = $key;
}
else {
$ret[$key] = $value;
}
}
return array_values($ret);
}
$arr = array("yassine#m","yassine#f","Dolmi#m", "yassine#l");
$list = generateUniqueList ($arr);
print_r($list);
Related
Let's suppose I have an array of arrays:
$A=array();
$A['lemonade']=array('a','b','g');
$A['tree']=array('a','b','f');
$A['willpower']=array('a','b','g');
How may i randomly grab one key of $A, but only of those containing 'g' in $A[n][2]?
The direct approach is to iterate though them all, create a new array containing only the arrays containing g, and then grabbing a random key in that new array.
$bro=array();
foreach($A as $k=>$hijito){
if($hijito[2]=='g'){
$bro[$k]=$hijito;
}
}
$theKeyIWant=array_rand($bro);
But I wonder if there is some other fancier way to approach this.
There is also this method using array_walk(DEMO):
$A = array();
$A['lemonade'] = array('a','b','g');
$A['tree'] = array('a','b','f');
$A['willpower'] = array('a','b','g');
$bro = $A;
array_walk($A, function($item, $key) use (&$bro)
{
if($item[2] != 'g')
{
unset($bro[$key]);
}
});
var_dump($bro);
Try This. First I filter the array and then get random key.
$A=array();
$A['lemonade']=array('a','b','g');
$A['tree']=array('a','b','f');
$A['willpower']=array('a','b','g');
$theKey = array_rand($filteredArr = array_filter($A, function($arr){
return ($arr[2] == 'g');
}));
echo $theKey;
try it with Array Iterator. have a look on below solution:
$n = 2; //key which need to be checked
$v = 'g'; //value which need to be checked
$key_array = array();
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($A));
foreach ($it as $key => $val) {
$pkey = $it->getSubIterator($it->getDepth() - 1)->key(); //get parent key
if($key == $n && $val == $v){
$key_array[$pkey] = $A[$pkey];
}
}
print_r($key_array); //desired array
print_r(array_rand($key_array)); //desired key
$data = array
(
array("Ravi","Kuwait",350),
array("Sameer","UK",400),
array("Aditi","Switzerland",50),
array("Akshay","India",250),
array("rishi","Singapore",200),
array("Mukul","Ireland",100)
);
I want to put condition to the third row such that I can get entries of less than 300.
I suppose that you meant "the third element" in each nested array.Use array_filter function to get an array of elements, those third element's value is less than 300:
$result = array_filter($data, function($v) { return $v[2] < 300; });
print_r($result);
Try this code:
<?php
$data = array
(
array("Ravi","Kuwait",350),
array("Sameer","UK",400),
array("Aditi","Switzerland",50),
array("Akshay","India",250),
array("rishi","Singapore",200),
array("Mukul","Ireland",100)
);
$newArray = array();
foreach($data as $key => $value)
{
if($value[2] <= 100)
$newArray[] = $value;
}
print_r($newArray);
?>
You can achieve this using the PHP function array_filter() :
PHP
function limitArray($array) {
return ($array[2] <= 300);
}
print_r(array_filter($data, 'limitArray'));
evalIN
I am trying to manually sort a PHP array without making use of ksort.
This is how my code looks at the moment:
function my_ksort(&$arg){
foreach($arg as $key1 => $value1){
foreach($arg as $key2 => $value2){
if($key1 > $key2){
$aux = $value2;
$arg[$key2] = $value1;
$arg[$key1] = $aux;
}
}
}
}
It doesn't sort, I can't figure out how to make it sort.
You could try this:
function my_ksort(&$arg)
{
$keys=array_keys($arg);
sort($keys);
foreach($keys as $key)
{
$val=$arg[$key];
unset($arg[$key]);
$arg[$key]=$val;
}
}
I'm sorting the keys separately and then deleting the elements one-by-one and appending them to the end, in ascending order.
I'm using another sorting function (sort()), but if you want to eliminate all available sorting functions from your emulation, sort() is much easier to emulate. In fact, #crypticous's algorithm does just that!
This function return array in ASC. Take in consideration that I'm using goto which is supported in (PHP 5 >= 5.3.0)
function ascending_array($array){
if (!is_array($array)){
$array = explode(",", $array);
}
$new = array();
$flag = true;
iter:
$array = array_values($array); // recount array values with new offsets
(isset($min["max"])) ? $min["value"] = $min["max"] : $min["value"] = $array[0];
$min["offset"] = 0;
for ($i=0;$i<count($array);$i++){
if ($array[$i] < $min["value"]){ // redefine min values each time if statement executed
$min["value"] = $array[$i];
$min["offset"] = $i;
}
if ($flag){ // execute only first time
if ($array[$i] > $min["value"]){ // define max value from array
$min["max"] = $array[$i];
}
$flag = false;
}
if ($i === (count($array)-1)){ // last array element
array_push($new,$min["value"]);
unset($array[$min["offset"]]);
}
}
if (count($array)!=0){
goto iter;
}
print_r($new);
}
$arr = array(50,25,98,45);
ascending_array($arr); // 25 45 50 98
PS. When I was studying php, I wrote this function and now remembered that I had it (that's why I really don't remember what I am doing in it, though fact is it's working properly and hopefully there are comments too), hope you'll enjoy :)
DEMO
I was checking some issue related to this post and i wanted to give my insight about it ! here's what i would have done to implement php's sort :
$array_res = array();
$array = array(50,25,98,45);
$i=0;
$temp = $array[0];
$key = array_search($temp, $array);
while ($i<count($array)-1){
$temp = $array[0];
for($n=0;$n<count($array) ;$n++)
{
if($array[$n]< $temp && $array[$n] != -1 )
{
$temp = $array[$n];
}
else{continue;}
}
//get the index for later deletion
$key = array_search($temp, $array);
array_push($array_res, $temp);
/// flag on those which were ordered
$array[$key] =-1;
$i++;
}
// lastly append the highest number
for($n=0;$n<count($array) ;$n++)
{
if ($array[$n] != -1)
array_push($array_res, $array[$n]);
}
// display the results
print_r($array_res);
This code will display : Array
(
[0] => 25
[1] => 45
[2] => 50
[3] => 98
)
Short and sweet
function custom_ksort($arg)
{
$keys = array_keys($arg);
sort($keys);
foreach($keys as $newV)
{
$newArr[$newV] = $arg[$newV];
}
return $newArr;
}
It looks like your issue is that you're changing "temporary" characters $key1 and $key2 but not the actual arrays. You have to change $arg, not just $key1 and $key2.
Try something like:
$arr = Array(3=>"a",7=>"b");
print_r( $arr );
foreach( $arr as $k=>$v ){
unset($arr[$k]);
$arr[$k+1] = $v;
}
print_r($arr);
I have an array like this:
[0] = 2
[1] = 8
[2] = 7
[3] = 7
And I want to end up with an array that looks like:
[0] = 7
[1] = 7
Basically, remove all elements where they occur less than twice.
Is their a PHP function that can do this?
try this,
$ar1=array(2,3,4,7,7);
$ar2=array();
foreach (array_count_values($ar1) as $k => $v) {
if ($v > 1) {
for($i=0;$i<$v;$i++)
{
$ar2[] = $k;
}
}
}
print_r($ar2);
output
Array ( [0] => 7 [1] => 7 )
Something like this would work, although you could probably improve it with array_reduce and an anonymous function
<?php
$originalArray = array(2, 8, 7, 7);
foreach (array_count_values($originalArray) as $k => $v) {
if ($v < 2) {
$originalKey = array_search($k, $originalArray);
unset($originalArray[$originalKey]);
}
}
var_dump(array_values($originalArray));
$testData = array(2,8,7,7,5,6,6,6,9,1);
$newArray = array();
array_walk(
array_filter(
array_count_values($testData),
function ($value) {
return ($value > 1);
}
),
function($counter, $key) use (&$newArray) {
$newArray = array_merge($newArray,array_fill(0,$counter,$key));
}
);
var_dump($newArray);
Though it'll give a strict standards warning. To avoid that, you'd need an interim stage:
$testData = array(2,8,7,7,5,6,6,6,9,1);
$newArray = array();
$interim = array_filter(
array_count_values($testData),
function ($value) {
return ($value > 1);
}
);
array_walk(
$interim,
function($counter, $key) use (&$newArray) {
$newArray = array_merge($newArray,array_fill(0,$counter,$key));
}
);
var_dump($newArray);
You could use a combination of array_count_values (which will give you an associative array with the value as the key, and the times it occurs as the value), followed by a simple loop, as follows:
$frequency = array_count_values($yourArray);
foreach ($yourArray as $k => $v) {
if (!empty($frequency[$v]) && $frequency[$v] < 2) {
unset($yourArray[$k]);
}
}
I did not test it, but I reckon it works out of the box. Please note that you will loop over your results twice and not N^2 times, unlike an array_search method. This can be further improved, and this is left as an exercise for the reader.
This was actually harder to do than i thought...anyway...
$input = array(2, 8, 7, 7, 9, 9, 10, 10);
$output = array();
foreach(array_count_values($input) as $key => $value) {
if ($value > 1) $output = array_merge($output, array_fill(0, $value, $key));
}
var_dump($output);
$arrMultipleValues = array('2','3','5','7','7','8','2','9','11','4','2','5','6','1');
function array_not_unique($input)
{
$duplicatesValues = array();
foreach ($input as $k => $v)
{
if($v>1)
{
$arrayIndex=count($duplicatesValues);
array_push($duplicatesValues,array_fill($arrayIndex, $v, $k));
}
}
return $duplicatesValues;
}
$countMultipleValue = array_count_values($arrMultipleValues);
print_r(array_not_unique($countMultipleValue));
Is their [sic!] a PHP function that can do this?
No, PHP has no built-in function (yet) that can do this out of the box.
That means, if you are looking for a function that does this, it needs to be in PHP userland. I would like to quote a comment under your question which already suggest you how you can do that if you are looking for that instead:
array_count_values() followed by a filter with the count >1 followed by an array_fill() might work
By Mark Baker 5 mins ago
If this sounds a bit cryptic to you, those functions he names are actually built-in function in PHP, so I assume this comes most close to the no, but answer:
array_count_values()
array_fill()
This does the job, maybe not the most efficient way. I'm new to PHP myself :)
<?php
$element = array();
$element[0] = 2;
$element[1] = 8;
$element[2] = 7;
$element[3] = 7;
$count = array_count_values($element);
var_dump($element);
var_dump($count);
$it = new RecursiveIteratorIterator( new RecursiveArrayIterator($count));
$result = array();
foreach ($it as $key=>$val){
if ($val >= 2){
for($i = 1; $i <= $val; $i++){
array_push($result,$key);
}
}
}
var_dump($result);
?>
EDIT: var_dump is just so you can see what's going on at each stage
Hi I need help in removing values from an array using a recursive function
$array = [0] => testing,testing1
[1] => testing,testing1,testing2
[2] => testing,testing1,testing2,testing3
[3] => testing,testing1,testing2,testing3,tesing4
[4] => testing,testing1,testing2,testing3,tesing4
[5] => testing,testing1,testing2,testing3,tesing4
[6] => testing,testing1,testing2,testing3,tesing4
[7] => testing,testing1,testing2,testing3,tesing4
I need to check the array count, ie if count(array[0]) == count(array[1]),then reutrn array
else unset(array[value]);
From the above array I have to remove array[0],[1],[2] and return rest of the array values.
I've tried the below code
$idx =10;
$separtor =',';
function array_delete($idx, $array,$separtor) {
$finalvalue = array();
for ($i = 0; $i < $idx; $i++) {
$values = explode($separtor, $array[$i]);
$valuesnext = explode($separtor, $array[$i+1]);
if(count($values) != count($valuesnext) )
{
unset($array[$i]);
// reset($array);
// array_delete($idx, $array,$separtor);
if (is_array($array)) $array = array_delete($idx, $array,$separtor);
$finalvalue = $array;
}else
{
}
//echo $i;
}
return $finalvalue;
//(is_array($array)) ? array_values($array) : null;
//array_delete($idx, $array,$separtor);
}
I'm getting Notice: Undefined offset: 0 when trying calling recursive, going to infinite loop
Do you want to keep the sub-arrays that have the most items? Your descriptions appear to say this.
If so, something like the following would suffice.
// Get maximum number of items in the arrays
$max_count = max(array_map('count', $array));
// Keep only those arrays having $max_count items
$filtered = array_filter($array, function ($a) use ($max_count) {
return count($a) === $max_count;
});
Aside: if you need the filtered array to have zero-based keys, call array_values() on it.
See an example running online.
If I understand correctly, you want to filter the array such that any value in the final array is of the same length as the last element in the source array. In order to avoid mutating an array while iterating over it, this technique builds a fresh array with the elements that match your criteria.
$matchLength = count($mainArray[count($mainArray) - 1]);
$resultArray = array();
for($i = 0; $i < count($mainArray); $i++) {
if(count($mainArray[$i]) == $matchLength) {
$resultArray[] = $mainArray[$i];
}
}
If you happen to be using PHP 5.3 or greater, you can do this quicker with closures and array_filter:
$matchLength = count($mainArray[count($mainArray) - 1]);
$resultArray = array_filter($mainArray, function($element){return count($element) == $matchLength});
Double check the code, I haven't been writing PHP lately, so this is just an idea.
According to the description you gave, it could be just made (check the count of the current and the provious one, if they don't match, remove the previous one).
Example/Demo:
unset($prevKey);
$count = array();
foreach (array_keys($array) as $key) {
$count[$key] = count($array[$key]);
if (isset($prevKey) && $count[$prevKey] !== $count[$key]) {
unset($array[$prevKey]);
}
$prevKey = $key;
}
If you need to re-iterate to take removals into account, a little goto can do the job Demo:
start:
######
unset($prevKey);
$count = array();
foreach (array_keys($array) as $key) {
$count[$key] = count($array[$key]);
if (isset($prevKey) && $count[$prevKey] !== $count[$key]) {
unset($array[$prevKey]);
goto start;
###########
}
$prevKey = $key;
}