4
\$\begingroup\$

I'm trying to achieve a set of unique array with my following function.

The Function:

/**
* uniqueAssocArray Removes arrys which have same keys
* @param Array $array Array to get unique items from
* @param String $uniqueKey the unique key 
* @return Array new array with unique items
* @author Junaid Qadir Baloch <[email protected]>
*/
function uniqueAssocArray($array, $uniqueKey) {
 if (!is_array($array)) {
 return array();
 }
 $uniqueKeys = array();
 foreach ($array as $key => $item) {
 if (!in_array($item[$uniqueKey], $uniqueKeys)) {
 $uniqueKeys[$item[$uniqueKey]] = $item;
 }
 }
 return $uniqueKeys;
}

Example Array:

$actualArray = array(
 user1 => array(
 'name' => 'User1',
 'age' => '25',
 'lastLogin' => '2013-08-16'
 ),
 user1 => array(
 'name' => 'User1',
 'age' => '25',
 'lastLogin' => '2013-08-10'
 ),
 user2 => array(
 'name' => 'User2',
 'age' => '35',
 'lastLogin' => '2013-08-08'
 ),
 user1 => array(
 'name' => 'User1',
 'age' => '25',
 'lastLogin' => '2013-07-10'
 )
);

I then call the function like so:

$resultArray = uniqueAssocArray($actualArray, 'name');

But...

I wonder is there a better way to do the same ?

asked Aug 16, 2013 at 10:55
\$\endgroup\$
0

2 Answers 2

2
\$\begingroup\$

Assuming your array is already sorted, you can just overwrite the values every time. Skip the inner if.

function uniqueAssocArray($array, $uniqueKey) {
 if (!is_array($array)) {
 return array();
 }
 $uniqueKeys = array();
 foreach ($array as $key => $item) {
 $groupBy=$item[$uniqueKey];
 if (isset( $uniqueKeys[$groupBy]))
 {
 //compare $item with $uniqueKeys[$groupBy] and decide if you 
 //want to use the new item
 $replace= ... 
 }
 else
 {
 $replace=true;
 }
 if ($replace) $uniqueKeys[$groupBy] = $item; 
 }
 return $uniqueKeys;
}
answered Aug 16, 2013 at 12:00
\$\endgroup\$
5
  • \$\begingroup\$ Haha! i had already done the same but I have to accept your answer. There's one catch though, Array must be sorted in reverse order. and I test for existence for a key before I replace the values blindly. \$\endgroup\$ Commented Aug 16, 2013 at 16:55
  • \$\begingroup\$ @mnhgI hope you won't mind if i un-accept your answer. I'm still looking for a better way \$\endgroup\$ Commented Aug 17, 2013 at 3:54
  • \$\begingroup\$ If you want the last element each, you need an ascending order. You are just overwriting the value again and again until you are on the last key. \$\endgroup\$ Commented Aug 17, 2013 at 6:08
  • \$\begingroup\$ Yes, but what if the array is random? \$\endgroup\$ Commented Aug 17, 2013 at 8:36
  • \$\begingroup\$ If performance doesn't matter, sort it. If you want to handle this in the same loop just compare the current items key value with the already inserted. \$\endgroup\$ Commented Aug 17, 2013 at 8:45
1
\$\begingroup\$

Maybe you should try to use the function array_unique: http://php.net/manual/en/function.array-unique.php

If you prefer to go with your own solution, have a look at the method array_key_exists (http://www.php.net/manual/en/function.array-key-exists.php) to replace your condition:

if (!array_key_exists($key, $uniqueKeys)) {
 $uniqueKeys[$item[$uniqueKey]] = $item; 
}

A bit off-topic here, but you probably don't want to store a user's age but rather her birthday, to make sure it stays up-to-date.

answered Aug 16, 2013 at 11:56
\$\endgroup\$
1
  • \$\begingroup\$ If I get him right he wants to use the last not the first duplicate each. \$\endgroup\$ Commented Aug 16, 2013 at 12:36

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.