1

I have an array I'm pulling from a MySQL db and I need to reformat it into another array without any duplicates on a specific key.

Original array:

Array // $categories array
(
    [0] => Array
        (
            [name] => Body & Bath Products
            [keyword] => body-and-bath-products
        )
    [more ...]
)

New array structure:

Array // $links array
(
    [0] => Array
        (
            [keyword] => Body & Bath Products
            [link] => ./Body-and-Bath-Products
            [target] => _self
            [tooltip] => 1
        )
    [more ...]
)

Looping through with PHP:

$links = array();

foreach ($categories as $cat):
    if (in_array ($cat['name'], $links)):
        continue;
    else:
        $links[] = array(
            'keyword' => $cat['name'],
            'link' => './' . $this->url->cap_keyword($cat['keyword']),
            'target' => '_self',
            'tooltip' => true
        );
    endif;
endforeach;

But this isn't working, still getting all 534 entries in my $links array.

I know it's something simple but I'm just missing it somehow ...

4
  • Well mate the problem you have is $cat['name'] will never be a key in $links array. If you var_dump() your $links array you will see that the keys are actually indexes from 0 to n. Commented Sep 9, 2013 at 23:48
  • I understand that, how do I test the value of $links['keyword'] ? Commented Sep 9, 2013 at 23:49
  • 1
    i t would be smarter to remove the duplicates in the querry Commented Sep 9, 2013 at 23:51
  • can you talk about the recrods returned from the query and how you would like them structured (i.e. when you say "remove" duplicates what does this mean - group common values somehow, perform some sort of aggregation on duplicate values, etc.). You can probably achieve what you want in the query itself. Commented Sep 10, 2013 at 0:12

2 Answers 2

1

You could simply use another foreach loop...

$links = array();

foreach ($categories as $cat){

    foreach($links as $value){ // Loop through $links array
        if($value['keyword'] == $cat['name']) // Check if $cat['name'] is already in $links
            continue 2; // Skip rest of this loop and parent loop if it exists
    }


    $links[] = array(
        'keyword' => $cat['name'],
        'link' => './' . $this->url->cap_keyword($cat['keyword']),
        'target' => '_self',
        'tooltip' => true
        );
}
Sign up to request clarification or add additional context in comments.

Comments

0

The problem you have mate is you are populating the $links array with indexed keys and when you are checking if key exists in the said array you are using $cat['name'] variable as key. Since that is never actually in the $links array you get duplicates.

$links = array();

foreach ($categories as $cat):
    if (in_array ($cat['name'], $links)): // HERE YOU CHECK IF $links CONTAINS $cat['name'] HOWEVER YOU NEVER STORE $cat['name'] AS KEY
        continue;
    else:
        $links[] = array( // HERE YOU STORE EACH ENTRY WITH KEY AS INDEX FROM 0 TO N
            'keyword' => $cat['name'],
            'link' => './' . $this->url->cap_keyword($cat['keyword']),
            'target' => '_self',
            'tooltip' => true
        );
    endif;
endforeach;

The solution would be to store keys with $cat['name'] instead of index number.
$links = array();

foreach ($categories as $cat):
    if (array_key_exists ($cat['name'], $links)): 
        continue;
    else:
        $links[$cat['name']] = array( // You should save the entry using $cat['name'] as key for the entry this way when you do the in_array check you can prevent duplicates
            'keyword' => $cat['name'],
            'link' => './' . $this->url->cap_keyword($cat['keyword']),
            'target' => '_self',
            'tooltip' => true
        );
    endif;
endforeach;

You will need to substitute numerical keys with the key $cat['name'] and in_array() method with array_key_exists() method.

The problem with in_array() is it checks value of top array $links and $links never contains $cat['name'] as value because it's and array of arrays. The arrays in $links however do contain $cat['name'].

6 Comments

No that won't work, the keys need to be numeric. I need a different way to test other than in_array()
You need to use array_key_exists()
array_key_exists() searches for keys while in_array() searches for values in the given array. Obviously as you mentioned, $cat['name'] will never appear as a key so it won't be found with array_key_exists()
You did not check my solution at all. You tried using in_array to find $cat['name'] in $links which did not work as you had an array of arrays. Only way you could have kept your own code was to add $cat['name'] as keys and used array_key_exists() instead of in_array(). However you seem to have choose the unsafe way to do it.
How on earth is it unsafe?
|

Your Answer

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.