可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a array of associative arrays
aa[] = ('Tires'=>100, 'Oil'=>10, 'Spark Plugs'=>4 ); aa[] = ('Tires'=>454, 'Oil'=>43, 'Spark Plugs'=>3 ); aa[] = ('Tires'=>34, 'Oil'=>55, 'Spark Plugs'=>44 ); aa[] = ('Tires'=>454, 'Oil'=>43, 'Spark Plugs'=>45 ); aa[] = ('Tires'=>34, 'Oil'=>55, 'Spark Plugs'=>433 ); aa[] = ('Tires'=>23, 'Oil'=>33, 'Spark Plugs'=>44 );
Two Questions
How can I remove duplicates according tot he field 'Oil' is there a array_unique which I can provide a callback which acts as a custom comparator?
How can I sort by a custom field 'Spark Plugs'
回答1:
I don't know of a function you can use to do this. You will have to do a foreach over the values of the array and do the uniqueness checking manually.
Use the usort() function and provide a custom comparator.
回答2:
Instead of manually going and doing the usual duplicate checking, I did this
$aa2 = array() foeach($aa as $key => $value) { $aa2[$value['Oil']] = $value; } $aa = $aa2;
Then sorting was done by the key...
回答3:
For question 1, I think array_filter is what you need.
And, like Brian says, usort for your second question.
回答4:
The issue with remove dupes this way, is how do you determine which values remain, since you're talking about partial uniqueness.
This solution below just keeps the first to appear in index-order. It's not exactly elegant, but it works.
<?php $aa = array(); $aa[] = array('Tires'=>100, 'Oil'=>10, 'Spark Plugs'=>4 ); $aa[] = array('Tires'=>454, 'Oil'=>43, 'Spark Plugs'=>3 ); $aa[] = array('Tires'=>34, 'Oil'=>55, 'Spark Plugs'=>44 ); $aa[] = array('Tires'=>454, 'Oil'=>43, 'Spark Plugs'=>45 ); $aa[] = array('Tires'=>34, 'Oil'=>55, 'Spark Plugs'=>433 ); $aa[] = array('Tires'=>23, 'Oil'=>33, 'Spark Plugs'=>44 ); echo '<pre>'; print_r( arrayUniqeBySubKey( $aa, 'Oil' ) ); echo '</pre>'; function arrayUniqeBySubKey( $array, $key ) { $indexAggregates = array(); foreach ( $array as $idx => $subArray ) { $indexAggregates[$subArray[$key]][] = $idx; } foreach ( $indexAggregates as $originalIndexes ) { $numOriginals = count( $originalIndexes ); if ( 1 == $numOriginals ) { continue; } for ( $i = 1; $i < $numOriginals; $i++ ) { unset( $array[$originalIndexes[$i]] ); } } return $array; }
回答5:
You can indeed use array_filter for filtering your data:
$bb = array_filter($aa, function($item) { static $tmp = array(); if ($filter = !in_array($item['Oil'], $tmp)) { $tmp[] = $item['Oil']; } return $filter; });
This uses a static variable inside the function to "remember" the Oil already returned. This works, because $tmp is used only during the execution of array_filter. If you wrap this into a function and call it multiple times for example, $tmp will always be an empty array for the first call of the function provided to array_filter.
The second task, the sorting, can be done using usort with a custom sorting function:
usort($bb, function($a, $b) { return ($a['Spark Plugs'] > $b['Spark Plugs'] ? 1 : -1); });