Multidimensional Array - Get unique values, but count all duplicates - php

I have a multi-dimensional array that I would like to get unique sub-values from, but also have a count of how many times those unique sub-values occurred.
For instance, this would be my starting array:
[0] => Array
(
[0] => Array
(
[id] => 1533438473619168
)
[1] => Array
(
[id] => 3333333333333333
)
)
[1] => Array
(
[0] => Array
(
[id] => 1533438473619168
)
[1] => Array
(
[id] => 5555555555555555
)
)
[2] => Array
(
[0] => Array
(
[id] => 1533438473619168
)
[1] => Array
(
[id] => 77777777777777777
)
)
In the end, I'd like to have an array that looks like this:
[0] => Array
(
[0] => Array
(
[id] => 1533438473619168
[count] => 3
)
[1] => Array
(
[id] => 3333333333333333
[count] => 1
)
[2] => Array
(
[id] => 5555555555555555
[count] => 1
)
[3] => Array
(
[id] => 77777777777777777
[count] => 1
)
)
Is there any general/easy way to do this without iterating through the first array for each value, comparing/storing the values in a temporary array, checking them, and adding to the count?

To get this exact format you may need to iterate thought your current array and do the counting manually, however php has the array_count_values() and array_unique() functions for this kind of thing:
http://php.net/manual/en/function.array-count-values.php
http://php.net/manual/en/function.array-unique.php

Because you are only concerned with the deepest values of the array, using array_walk_recursive seems suitable for this. Note that a reference to the output array $counted is used in the callback.
array_walk_recursive($ids, function($id, $k) use (&$counted) {
$counted[$id] = isset($counted[$id]) ? $counted[$id] + 1 : 1;
});
Using the id as the key in the $counted array will simplify the counting. The result of this will be somewhat different from your suggested output, but in my opinion it would actually be simpler to use. (e.g. foreach ($counted as $id => $count) {...).
$counted = array(
"1533438473619168" => 3
"3333333333333333" => 1
"5555555555555555" => 1
"77777777777777777" => 1);

Related

Search multidimensional array for value

I wonder if there is better (faster) way to search for value in multidimensional array than looping through every item.
Lets say i have
$id_to_search = '16819976033';
And array which is pretty big
Array
(
[0] => Array
(
[id] => Array
(
[0] => 16771055710
[1] => 16776555710
[2] => 16819976033
)
[o] => 21566
[p] => 12597.66
)
[1] => Array
(
[id] => Array
(
[0] => 14089762
)
[o] => 12606
[p] => 1747.49
)
etc ...
)
I can find it if i loop through each item and than compare them but its very slow because array is big.
You can use by array_search function in PHP:
$key = array_search($id_to_search, array_column($YourArray, 'id'));

PHP array - count unique IDs

I have a PHP array that looks like this
Array
(
[0] => Array
(
[events] => Array
(
[0] => Array
(
[label] => apple
[id] => 3
)
[1] => Array
(
[label] => onion
[id] => 3
)
[2] => Array
(
[label] => pear
[id] => 2
)
[3] => Array
(
[label] => orange
[id] => 1
)
[4] => Array
(
[label] => grape
[id] => 41
)
)
)
)
I am trying to get a total count of unique IDs, so in the example above I would want to get a count of 4
Do I need to loop through the array or is there a function that can do it more efficiently? Currently it is a small data set but it could grow fairly large.
You can use array_column to get all the IDs, and array_unique to remove the duplicates, then count that.
count(array_unique(array_column($array[0]['events'][0], 'id')))
One way or another you'll have to loop through it. I think most efficiently would be
function getUnique($arr){
$val = array();
foreach($arr[0]["events"] as $v){
$val[$v["id"]] = true;
}
return count($val);
}

What does [1] => 0 mean in this array?

I know this must be a fairly simple question, but I haven't managed to stumble across an answer yet.
I have the following array
$qid[0][0]=1;
$qid[1][0]=2;
$qid[2][0]=3;
$qid[3][0]=4;
When I use print_r($qid) I get the following
Array (
[0] => Array ( [0] => 1 [1] => 0 )
[1] => Array ( [0] => 2 )
[2] => Array ( [0] => 3 )
[3] => Array ( [0] => 4 )
)
I don't understand [1] => 0
in
[0] => Array ( [0] => 1 [1] => 0 )
If someone could explain what [1] => 0 means in this array, I'd greatly appreciate it. Thanks.
EDIT: It turns out that my array was indeed different to what I had written above, because it had been modified later in the code. Thanks everyone for the great answers. I'm still reading over them all and trying to make my mind understand them (Arrays turn my mind to jello).
[1] => 0 denotes an array element with the value 0.
The numbers in [] are array keys. So [1] is the second element of a numerically indexed array, (which starts with [0]), and the value of the second element ([1]) is 0.
PHP uses => as an operator to relate array keys/indices to their values.
So an overall explanation of this structure:
Array (
[0] => Array ( [0] => 1 [1] => 0 )
[1] => Array ( [0] => 2 )
[2] => Array ( [0] => 3 )
[3] => Array ( [0] => 4 )
)
The outer array is a numerically indexed array, and each of its elements is a sub-array. The first of them ([0]) is an array containing 2 elements, while the rest of them ([1] through [3]) are arrays containing only one single element.
That two-dimensional array is actually a one-dimensional array of arrays, which is why you're getting the nesting. The [x] => y bit simply means that index x of the array has the value y.
Now your output in this case doesn't actually match your code, since
$qid[0][0]=1;
$qid[1][0]=2;
$qid[2][0]=3;
$qid[3][0]=4;
print_r($qid);
produces:
Array (
[0] => Array ( [0] => 1 )
[1] => Array ( [0] => 2 )
[2] => Array ( [0] => 3 )
[3] => Array ( [0] => 4 )
)
If you wanted to get:
Array (
[0] => Array ( [0] => 1 [1] => 0 )
[1] => Array ( [0] => 2 )
[2] => Array ( [0] => 3 )
[3] => Array ( [0] => 4 )
)
(with the first array having two elements), you'd actually need:
$qid[0][0]=1;
$qid[0][1]=0;
$qid[1][0]=2;
$qid[2][0]=3;
$qid[3][0]=4;
print_r($qid);
You probably added a second item to $qid[0] somewhere ($qid[0][1] = 0). This code
$qid[0][0]=1;
$qid[1][0]=2;
$qid[2][0]=3;
$qid[3][0]=4;
outputs the the correct values for me (without [1] => 0:
Array ( [0] => Array ( [0] => 1 ) [1] => Array ( [0] => 2 ) [2] => Array ( [0] => 3 ) [3] => Array ( [0] => 4 ) )
It means that your index 0 in the original Array contains another Array of 2 items.
Specifically [1] => 0 means that the 2nd item of the "child" Array contains the number 0.
[1] => 0
in this simple way we can say that 1 is your array key and 0 is value for the 1 key
0 is store at the 1 key of the array
thanks
Simply put, you have a numerically indexed multidimensional array. http://php.net/manual/en/language.types.array.php should have all the information you need to read up on this.
As to why you have the [1] => 0, you'll need to look a little deeper into your code to see where it gets assigned.
I got the following result after printing out the array using print_r:
Array
(
[0] => Array
(
[0] => 1
)
[1] => Array
(
[0] => 2
)
[2] => Array
(
[0] => 3
)
[3] => Array
(
[0] => 4
)
)
I guess, you might have set a value for $gid[0][1] somewhere in your code.

Sort MultiDimensional Array created By Object Class by multiple keys

What I'd like to do is sort this multidimensional array by multiple keys. I've attempted to use array_multisort() but haven't had luck because of the type of array.
A function that can have multiple keys to it to sort by (relevancy, date) would be best so that other arrays with the same structure could use it as well.
This is the $array I'm working with:
Array
(
[0] => DALQueryResult Object
(
[_results:DALQueryResult:private] => Array
(
[0] => 32048
[id] => 32048
[1] => 1
[relevancy] => 1
)
)
[1] => DALQueryResult Object
(
[_results:DALQueryResult:private] => Array
(
[0] => 32002
[id] => 32002
[1] => 1
[relevancy] => 1
)
)
[2] => DALQueryResult Object
(
[_results:DALQueryResult:private] => Array
(
[0] => 31921
[id] => 31921
[1] => 1
[relevancy] => 1
)
)
[3] => DALQueryResult Object
(
[_results:DALQueryResult:private] => Array
(
[0] => 31868
[id] => 31868
[1] => 1
[relevancy] => 1
)
)
[4] => DALQueryResult Object
(
[_results:DALQueryResult:private] => Array
(
[0] => 31811
[id] => 31811
[1] => 1
[relevancy] => 1
)
)
)
I've tried this function (found here), but haven't had luck:
$sort = array();
foreach($array as $k=>$v) {
$sort['relevancy'][$k] = $v['relevancy'];
$sort['date'][$k] = $v['date'];
}
# sort by event_type desc and then title asc
array_multisort($sort['relevancy'], SORT_DESC, $sort['date'], SORT_DESC, $array);
After running array_multisort function I see this:
Fatal error: Cannot use object of type DALQueryResult as array
I take it you are using code that can be found here. If so, just modify your SQL query with:
ORDER BY relevancy, date
In your case it doesn't work because DALQueryResult is not an array, so $v['relevancy'] will cause an error (it should be $v->relevancy). Even if you changed it, it wouldn't work because DALQueryResult is an object, not an array (and it doesn't implement ArrayAccess either).
I'd also suggest you use PDO instead of a random class found on the web (if that's the case, of course). :)

php merging two arrays into one

I have two arrays that need to be merged together and trying to figure out the correct way of doing it.
this is the first array
Array
(
[IndividualOutmsg] => Array
(
[0] => Array
(
[user_id] => 3
[number] => 414566765
[msg] => some message
)
[1] => Array
(
[user_id] => 3
[number] => 410335509
[msg] => any message
)
)
)
this is the second array:
Array
(
[0] => Array
(
[0] => OK
[1] => 0
[2] => d142b46128b869d0
[3] => 6178977058476937
)
[1] => Array
(
[0] => OK
[1] => 0
[2] => 60f403f4e243e684
[3] => 6198708709873543
)
)
what i want to get is this:
Array
(
[IndividualOutmsg] => Array
(
[0] => Array
(
[user_id] => 3
[number] => 414566765
[msg] => some message
[sms_status] => OK
[error_code] => 0
[msg_id] => d142b46128b869d0
[msg_id_2] => 6178977058476937
)
[1] => Array
(
[user_id] => 3
[number] => 410335509
[msg] => any message
[sms_status] => OK
[error_code] => 0
[msg_id] => 60f403f4e243e684
[msg_id_2] => 6198708709873543
)
)
)
In that format, you really have to do a lot of the legwork yourself and can't just use array_merge to combine the arrays. It would have to be a more custom job, like so:
$count = count($second_array);
for($i=0; $i<$count; $i++){
$first_array['IndividualOutmsg'][$i]['sms_status'] = $second_array[0];
$first_array['IndividualOutmsg'][$i]['error_code'] = $second_array[1];
$first_array['IndividualOutmsg'][$i]['msg_id'] = $second_array[2];
$first_array['IndividualOutmsg'][$i]['msg_id2'] = $second_array[3];
}
If you were to output the second array with the associative keys set, it would be much easier to combine them using array_merge, provided the keys didn't conflict.
$count = count($second_array);
for($i=0; $i<$count; $i++){
$first_array['IndividualOutmsg'][$i] =
array_merge($first_array['IndividualOutmsg'][$i], $second_array[$i]);
}
http://au.php.net/manual/en/function.array-merge.php
Array merge might be what you're looking for...
Though you'll need to probably write a loop or function that can get to the right place in your multi-dimensional array, perform the merge and also change the relevant keys.

Categories