I have an array like this:
$names = array('John Doe','Marc','Rudolph', 'John Doe','Steve', 'Marc');
How can i remove the duplicate names with PHP?
The new array must be:
$names = array('John Doe','Marc','Rudolph','Steve');
What is already the function to do this.?
Always check the php.net manual first.
$names = array('John Doe','Marc','Rudolph', 'John Doe','Steve', 'Marc');
$names = array_unique($names);
http://php.net/manual/en/function.array-unique.php
Use array_unique():
$myArray = array(....);
$uniqueArray = array_unique( $myArray );
See docs: http://php.net/manual/en/function.array-unique.php
You can use array_unique But please note that this would not work for case sensitive array such as
$names = array('John Doe','Marc','Rudolph','John doe','Steve','Marc');
^-- Capital ^--Small
If you run
var_dump(array_unique($names));
Output
array
0 => string 'John Doe' (length=8)
1 => string 'Marc' (length=4)
2 => string 'Rudolph' (length=7)
3 => string 'John doe' (length=8)
4 => string 'Steve' (length=5
Solution Convert everything to the same case before you check if it unique
var_dump(arrayUnique($names));
Output
array
0 => string 'John Doe' (length=8)
1 => string 'Marc' (length=4)
2 => string 'Rudolph' (length=7)
4 => string 'Steve' (length=5)
Function Used
function arrayUnique($array) {
return array_intersect_key($array, array_unique(array_map("strtolower", $array)));
}
Related
I'm trying to create a function that shifts array values up a key if the previous key is empty and one after is set. E.g. this array:
array (size=4)
'row1' => string 'row1' (length=4)
'row2' => string '' (length=0)
'row3' => string '' (length=0)
'row4' => string 'row4' (length=4)
should become this after my function call:
array (size=4)
'row1' => string 'row1' (length=4)
'row2' => string 'row4' (length=4)
'row3' => string '' (length=0)
'row4' => string '' (length=0)
I do have a working function, however, it uses a lot of if statements and I'm 100% sure that it could be done more efficiently, any ideas on how to achieve efficiently?
Thanks
You can do this in a single line, making use of array_ functions.
$o = array_combine(array_keys($input), array_pad(array_filter($input), count($input), ''));
array_filter will, by default, remove any empty values from the array
array_pad will pad the array to the length of the original array, adding an empty string
array_keys will get the keys of the original array
array_combine will combine the keys with the values
The above would output the following:
array (size=4)
'row1' => string 'row1' (length=4)
'row2' => string 'row4' (length=4)
'row3' => string '' (length=0)
'row4' => string '' (length=0)
Here's a demo
Lets try this with a big array, and hope this will help you out. The way of question is different but your question is same as
1. Getting empty values at end.
2. Non empty at starting without changing order
3. Without changing keys order
If you think about any array this result come to end.
Try this code snippet here
<?php
$array=$tempArray=array(
'row1' => 'row1',
'row2' => '' ,
'row3' => '',
'row6' => 'row6' ,
'row4' => 'row4' ,
'row5' => '',
'row7' => 'row7' ,
'row8' => ''
);
$result=array();
$tempArray= array_values($tempArray);
$tempArray=array_values(array_filter($tempArray));
foreach(array_keys($array) as $key_key => $key)
{
if(!empty($tempArray[$key_key]))
{
$result[$key]=$tempArray[$key_key];
}
else
{
$result[$key]="";
}
}
print_r($result);
Output:
Array
(
[row1] => row1
[row2] => row6
[row3] => row4
[row6] => row7
[row4] =>
[row5] =>
[row7] =>
[row8] =>
)
unfortunately you did not share your code, so we cannot know what you do exactly
also it would be helpful if you added the array as code we can run directly and do not need to edit/re-create
I would
ignore the keys for processing the list when possible
unset entries that are nor needed any longer
iterate lists with foreach
apart from this you can sort lists in PHP (by value, key; asc, desc; with/without association), they have a nice overview on that in the manual.
example steps:
<?php
$a['row1'] = 'row1';
$a['row2'] = '';
$a['row3'] = '';
$a['row4'] = 'row4';
print_r( $a );
arsort($a);
print_r( $a );
//get rid of double entries
$f=array_flip( $a );
//get rid of empty entries
unset($f['']);
print_r( array_flip( $f ) );
?>
EDIT
$yourarr=array('row1'=>"row1",'row2'=>"",'row3'=>"",'row4'=>"row4");
$array1=array();
$array2=array();
foreach ($yourarr as $key =>$val){
if(empty($val)){
$array2[$key]=$val;
}else{
$array1[$key]=$val;
}
}
$newarr=array_merge($array1,$array2);
//<!-- Try This if you want to remove the empty indexes just put ! infront of the empty and delete the else part and to reset the row count -->
$i=1;
$newarr2=array();
foreach($newarr as $key =>$val){
$newarr2['row'.$i]=$val;
$i++;
}
var_dump($newarr2);
OUTUT
D:\wamp64\www\test\index.php:21:
array (size=4)
'row1' => string 'row1' (length=4)
'row2' => string 'row4' (length=4)
'row3' => string '' (length=0)
'row4' => string '' (length=0)
Currently I have this:
$pattern = array('industry_id','category_id','subcategory_id');
$data = array('advert_id' => string '261501' (length=6)
'advert_type_id' => string '7' (length=1)
'user_id' => string '6221' (length=4)
'industry_id' => string '17' (length=2)
'category_id' => string '769' (length=3)
'subcategory_id' => string '868' (length=3)
'model' => string 'Custom Semi Drop Deck Trailer' (length=29)
'description' => string 'Industry: Trailer );
Then:
array_intersect_key( $data , array_flip($pattern) );
Using array_interect_key & array_flip to get the values from $data based on $pattern, I will get a result like this:
array (size=3)
'category_id' => string '769' (length=3)
'subcategory_id' => string '930' (length=3)
'industry_id' => string '17' (length=2)
Unfortunately as you can see the result key sorting is not the same that I declared in $pattern. Is there a shorthand way to sort it like I declared in $pattern because after this I want to implode the array and do something like this industry_id.category_id.subcategory_id without hard coding the keys.
Since you already figured out array_intersect_key method which will not get you the desired key ordering of $pattern, try this instead:
// since original $pattern is not ASSOC (only vals)
// flip it so defined vals become keys
$pattern_flipped = array_flip($pattern);
$result = array();
foreach ($pattern_flipped as $k => $v) {
if (isset($data[$k])) {
$result[$k] = $data[$k];
}
}
var_dump($result); // test
// can use original 0 1 2 dynamic keys for concatenation
echo $result[$pattern[0]], $result[$pattern[1]], $result[$pattern[2]], '<br>';
// or use hardcoded keys
echo $result['industry_id'], $result['category_id'], $result['subcategory_id'], '<br>';
You know I'm not sure how you're getting the result you describe. I've tried your code and I get
array (size=3)
'industry_id' => string '17' (length=2)
'category_id' => string '769' (length=3)
'subcategory_id' => string '868' (length=3)
You could do this another way though using array_filter
$newData = array_filter($data, function($key) use ($pattern) {
if (in_array($key, $pattern))
return true;
}, ARRAY_FILTER_USE_KEY)
I have a multi-array where I need to keep the first 3 index groups and remove the rest from the multiarray (in each group).
See multiarray here: https://gist.github.com/no1uknow/6887497
So:
In this example I need the multi-array to keep: The first 3 Heavy, Lite, Intermediate, etc (these are identified by the source_type_cd)
Example of the Lite part of the array after the first 3 are kept:
0 =>
array (size=9)
'validated_ata' => string '25' (length=2)
'source_type_cd' => string 'Lite' (length=4)
'validated_subata' => string '22' (length=2)
'action_cd' => string '3' (length=1)
'object_cd' => string '5' (length=1)
'malfunction_cd' => string '29' (length=2)
'corrective_action_txt' => string 'Repair-Passenger Seat-Loose / Displaced' (length=39)
'rec_count' => string '00050' (length=5)
'group_id' => int 48
1 =>
array (size=9)
'validated_ata' => string '25' (length=2)
'source_type_cd' => string 'Lite' (length=4)
'validated_subata' => string '22' (length=2)
'action_cd' => string '3' (length=1)
'object_cd' => string '5' (length=1)
'malfunction_cd' => string '1' (length=1)
'corrective_action_txt' => string 'Repair-Passenger Seat-Inoperative' (length=33)
'rec_count' => string '00047' (length=5)
'group_id' => int 44
2 =>
array (size=9)
'validated_ata' => string '25' (length=2)
'source_type_cd' => string 'Lite' (length=4)
'validated_subata' => string '22' (length=2)
'action_cd' => string '3' (length=1)
'object_cd' => string '5' (length=1)
'malfunction_cd' => string '31' (length=2)
'corrective_action_txt' => string 'Repair-Passenger Seat-Worn / Chaffed / Frayed' (length=45)
'rec_count' => string '00042' (length=5)
'group_id' => int 50
You will simply have to loop through the array and look if it has any of those values and place into a new array.
Example (where $arr is your multiarray):
// My silly solution for knowing what to look for
// When one is found, it will be removed from the array.
$find = array('Lite','Lite','Lite','Intermediate','Intermediate','Intermediate','Heavy','Heavy','Heavy');
// New array where your the values you want will be placed in
$new_arr = array();
foreach($arr as $v) {
// No need to keep looking if there's no more to find.
if(empty($find))
break;
// Look in $find array if current "source_type_cd" is still sought-after
$key = array_search($v['source_type_cd'], $find);
if($key !== false) {
$new_arr[] = $v; // Add to new array
unset($find[$key]); // Remove from "find" array
}
}
Thanks Colandus I actually figured it out like this... I was trying to avoid to many loops.
In a loop above this I set the source_type_cd in an array:
$groups[]=$value['source_type_cd']
Next I loop through the array and take the top 3 of each group by using array_splice twice and then merging back into a new array.
(also, I'm using a start and end point ($group_count).)
$start = 0;
$group_count = $i+1;
$top_count = 3;
foreach($groups as $k => $v) {
$top_count_array = array_merge((array)$top_count_array, (array)array_slice(array_slice($sorted_array, $start, $group_count, true),0,$top_count,true));
$start = $start+$group_count;
}
var_dump($top_count_array);
Again appreciate the input. Tried to shorten this code down from so many loops. Also requirements will change for grabbing the amount of $top_count and $group_count... Needed something a little more dynamic. :-)
I am using PHP 5.3.5, and I am stuck with an error. I have an array
$input = array(
0=>array(
'a'=>'one0',
'b'=>'two0',
'c'=>'three0',
'd'=>'four0',
'e'=>'five0'
),
1=>array(
'a'=>'one1',
'b'=>'two1',
'c'=>'three1',
'd'=>'four1',
'e'=>'five1'
)
);
I use array_splice to remove the initial two values from each array
by using &(value by reference) in foreach
foreach ($input as $bk => &$bv) {
$op[]=array_splice($bv,0,2);
}
Now when I see the $input then it adds a & just before the second array.
var_dump($input); shows this
array
0 =>
array
'c' => string 'three0' (length=6)
'd' => string 'four0' (length=5)
'e' => string 'five0' (length=5)
1 => & <====================================From where this `&` comes?
array
'c' => string 'three1' (length=6)
'd' => string 'four1' (length=5)
'e' => string 'five1' (length=5)
Where does & come from and how does it produce such array? Is it valid?
If I remove & in the foreach, it does not gives me desired array. Am I doing something wrong?
It's pretty counter-intuitive but it isn't actually a bug. When you use references in a loop, you're advised to unset the reference right after the loop:
foreach ($input as $bk => &$bv) {
$op[]=array_splice($bv,0,2);
}
unset($bv);
I would like a hint or much better a solution for this:
I do a regular expresion match to an url for example '/product/100/'
preg_match('/^\/(?<name>\w+)\/(?<digit>\d+)\/$/', '/product/100/', $matches);
As result of this I get the following array on $matches:
array
0 => string '/product/100/' (length=13)
'name' => string 'product' (length=7)
1 => string 'product' (length=7)
'digit' => string '100' (length=3)
2 => string '100' (length=3)
How can I use reduce this array to get this?
array
'name' => string 'product' (length=7)
'digit' => string '100' (length=3)
After I get the matching expresions, I call a function and give the 'named' keys as arguments to the function.
call_user_func_array($view, $just_named_args_no_integer_keys);
I hope anyone can give me any hint.
Best Regards
Just run the keys you get from array_keys() through array_filter():
/* This is for PHP 5.3, I'm sure you'll figure out how to the same thing pre 5.3 :) */
$allKeys = array_keys($view);
$namedKeys = array_filter($allKeys, function($value) { return !is_numeric($value); });
Update
Did not read the question properly. In this case, actually just foreach over the data:
$namedValues = array();
foreach ($view as $key => $value)
if (!is_numeric($key))
$namedValues[$key] = $value;