Use nubSort instead of nub . sort.

This commit is contained in:
Stephen Morgan 2020-01-04 17:09:01 +11:00 committed by Simon Michael
parent 390cea7f7c
commit 74778efcf5
22 changed files with 45 additions and 32 deletions

View File

@ -41,6 +41,7 @@ module Hledger.Data.AccountName (
where where
import Data.List import Data.List
import Data.List.Extra (nubSort)
#if !(MIN_VERSION_base(4,11,0)) #if !(MIN_VERSION_base(4,11,0))
import Data.Monoid import Data.Monoid
#endif #endif
@ -110,7 +111,7 @@ accountNameDrop n a
-- ie these plus all their parent accounts up to the root. -- ie these plus all their parent accounts up to the root.
-- Eg: ["a:b:c","d:e"] -> ["a","a:b","a:b:c","d","d:e"] -- Eg: ["a:b:c","d:e"] -> ["a","a:b","a:b:c","d","d:e"]
expandAccountNames :: [AccountName] -> [AccountName] expandAccountNames :: [AccountName] -> [AccountName]
expandAccountNames as = nub $ sort $ concatMap expandAccountName as expandAccountNames as = nubSort $ concatMap expandAccountName as
-- | "a:b:c" -> ["a","a:b","a:b:c"] -- | "a:b:c" -> ["a","a:b","a:b:c"]
expandAccountName :: AccountName -> [AccountName] expandAccountName :: AccountName -> [AccountName]

View File

@ -95,7 +95,7 @@ import Data.Function ((&))
import Data.Functor.Identity (Identity(..)) import Data.Functor.Identity (Identity(..))
import qualified Data.HashTable.ST.Cuckoo as H import qualified Data.HashTable.ST.Cuckoo as H
import Data.List import Data.List
import Data.List.Extra (groupSort) import Data.List.Extra (groupSort, nubSort)
import qualified Data.Map as M import qualified Data.Map as M
import Data.Maybe import Data.Maybe
#if !(MIN_VERSION_base(4,11,0)) #if !(MIN_VERSION_base(4,11,0))
@ -258,7 +258,7 @@ journalPrevTransaction j t = journalTransactionAt j (tindex t - 1)
-- | Unique transaction descriptions used in this journal. -- | Unique transaction descriptions used in this journal.
journalDescriptions :: Journal -> [Text] journalDescriptions :: Journal -> [Text]
journalDescriptions = nub . sort . map tdescription . jtxns journalDescriptions = nubSort . map tdescription . jtxns
-- | All postings from this journal's transactions, in order. -- | All postings from this journal's transactions, in order.
journalPostings :: Journal -> [Posting] journalPostings :: Journal -> [Posting]
@ -275,17 +275,17 @@ journalAccountNamesImplied = expandAccountNames . journalAccountNamesUsed
-- | Sorted unique account names declared by account directives in this journal. -- | Sorted unique account names declared by account directives in this journal.
journalAccountNamesDeclared :: Journal -> [AccountName] journalAccountNamesDeclared :: Journal -> [AccountName]
journalAccountNamesDeclared = nub . sort . map fst . jdeclaredaccounts journalAccountNamesDeclared = nubSort . map fst . jdeclaredaccounts
-- | Sorted unique account names declared by account directives or posted to -- | Sorted unique account names declared by account directives or posted to
-- by transactions in this journal. -- by transactions in this journal.
journalAccountNamesDeclaredOrUsed :: Journal -> [AccountName] journalAccountNamesDeclaredOrUsed :: Journal -> [AccountName]
journalAccountNamesDeclaredOrUsed j = nub $ sort $ journalAccountNamesDeclared j ++ journalAccountNamesUsed j journalAccountNamesDeclaredOrUsed j = nubSort $ journalAccountNamesDeclared j ++ journalAccountNamesUsed j
-- | Sorted unique account names declared by account directives, or posted to -- | Sorted unique account names declared by account directives, or posted to
-- or implied as parents by transactions in this journal. -- or implied as parents by transactions in this journal.
journalAccountNamesDeclaredOrImplied :: Journal -> [AccountName] journalAccountNamesDeclaredOrImplied :: Journal -> [AccountName]
journalAccountNamesDeclaredOrImplied j = nub $ sort $ journalAccountNamesDeclared j ++ journalAccountNamesImplied j journalAccountNamesDeclaredOrImplied j = nubSort $ journalAccountNamesDeclared j ++ journalAccountNamesImplied j
-- | Convenience/compatibility alias for journalAccountNamesDeclaredOrImplied. -- | Convenience/compatibility alias for journalAccountNamesDeclaredOrImplied.
journalAccountNames :: Journal -> [AccountName] journalAccountNames :: Journal -> [AccountName]

View File

@ -69,7 +69,7 @@ module Hledger.Data.Posting (
where where
import Data.Foldable (asum) import Data.Foldable (asum)
import Data.List import Data.List.Extra (nubSort)
import qualified Data.Map as M import qualified Data.Map as M
import Data.Maybe import Data.Maybe
import Data.MemoUgly (memo) import Data.MemoUgly (memo)
@ -190,7 +190,7 @@ hasBalanceAssignment p = not (hasAmount p) && isJust (pbalanceassertion p)
-- | Sorted unique account names referenced by these postings. -- | Sorted unique account names referenced by these postings.
accountNamesFromPostings :: [Posting] -> [AccountName] accountNamesFromPostings :: [Posting] -> [AccountName]
accountNamesFromPostings = nub . sort . map paccount accountNamesFromPostings = nubSort . map paccount
sumPostings :: [Posting] -> MixedAmount sumPostings :: [Posting] -> MixedAmount
sumPostings = sumStrict . map pamount sumPostings = sumStrict . map pamount

View File

@ -11,6 +11,7 @@ where
import Data.Decimal import Data.Decimal
import Data.List import Data.List
import Data.List.Extra (nubSort)
import Data.Maybe import Data.Maybe
#if !(MIN_VERSION_base(4,11,0)) #if !(MIN_VERSION_base(4,11,0))
import Data.Monoid ((<>)) import Data.Monoid ((<>))
@ -202,7 +203,7 @@ combineBudgetAndActual
(MultiBalanceReport (budgetperiods, budgetrows, (budgettots, budgetgrandtot, budgetgrandavg))) (MultiBalanceReport (budgetperiods, budgetrows, (budgettots, budgetgrandtot, budgetgrandavg)))
(MultiBalanceReport (actualperiods, actualrows, (actualtots, actualgrandtot, actualgrandavg))) = (MultiBalanceReport (actualperiods, actualrows, (actualtots, actualgrandtot, actualgrandavg))) =
let let
periods = nub $ sort $ filter (/= nulldatespan) $ budgetperiods ++ actualperiods periods = nubSort $ filter (/= nulldatespan) $ budgetperiods ++ actualperiods
-- first, combine any corresponding budget goals with actual changes -- first, combine any corresponding budget goals with actual changes
rows1 = rows1 =

View File

@ -24,6 +24,7 @@ where
import GHC.Generics (Generic) import GHC.Generics (Generic)
import Control.DeepSeq (NFData) import Control.DeepSeq (NFData)
import Data.List import Data.List
import Data.List.Extra (nubSort)
import qualified Data.Map as M import qualified Data.Map as M
import Data.Maybe import Data.Maybe
import Data.Ord import Data.Ord
@ -235,7 +236,7 @@ multiBalanceReportWith ropts@ReportOpts{..} q j priceoracle =
(if tree_ ropts then expandAccountNames else id) $ (if tree_ ropts then expandAccountNames else id) $
nub $ map (clipOrEllipsifyAccountName depth) $ nub $ map (clipOrEllipsifyAccountName depth) $
if empty_ || balancetype_ == HistoricalBalance if empty_ || balancetype_ == HistoricalBalance
then nub $ sort $ startaccts ++ allpostedaccts then nubSort $ startaccts ++ allpostedaccts
else allpostedaccts else allpostedaccts
where where
allpostedaccts :: [AccountName] = allpostedaccts :: [AccountName] =

View File

@ -23,8 +23,8 @@ module Hledger.Reports.PostingsReport (
where where
import Data.List import Data.List
import Data.List.Extra (nubSort)
import Data.Maybe import Data.Maybe
import Data.Ord (comparing)
-- import Data.Text (Text) -- import Data.Text (Text)
import qualified Data.Text as T import qualified Data.Text as T
import Data.Time.Calendar import Data.Time.Calendar
@ -166,7 +166,7 @@ matchedPostingsBeforeAndDuring opts q j (DateSpan mstart mend) =
where where
beforestartq = dbg1 "beforestartq" $ dateqtype $ DateSpan Nothing mstart beforestartq = dbg1 "beforestartq" $ dateqtype $ DateSpan Nothing mstart
beforeandduringps = beforeandduringps =
dbg1 "ps5" $ sortBy (comparing sortdate) $ -- sort postings by date or date2 dbg1 "ps5" $ sortOn sortdate $ -- sort postings by date or date2
dbg1 "ps4" $ (if invert_ opts then map negatePostingAmount else id) $ -- with --invert, invert amounts dbg1 "ps4" $ (if invert_ opts then map negatePostingAmount else id) $ -- with --invert, invert amounts
dbg1 "ps3" $ map (filterPostingAmount symq) $ -- remove amount parts which the query's cur: terms would exclude dbg1 "ps3" $ map (filterPostingAmount symq) $ -- remove amount parts which the query's cur: terms would exclude
dbg1 "ps2" $ (if related_ opts then concatMap relatedPostings else id) $ -- with -r, replace each with its sibling postings dbg1 "ps2" $ (if related_ opts then concatMap relatedPostings else id) $ -- with -r, replace each with its sibling postings
@ -254,7 +254,7 @@ summarisePostingsInDateSpan (DateSpan b e) wd depth showempty ps
summaryps | depth > 0 = [summaryp{paccount=a,pamount=balance a} | a <- clippedanames] summaryps | depth > 0 = [summaryp{paccount=a,pamount=balance a} | a <- clippedanames]
| otherwise = [summaryp{paccount="...",pamount=sum $ map pamount ps}] | otherwise = [summaryp{paccount="...",pamount=sum $ map pamount ps}]
summarypes = map (, e') $ (if showempty then id else filter (not . isZeroMixedAmount . pamount)) summaryps summarypes = map (, e') $ (if showempty then id else filter (not . isZeroMixedAmount . pamount)) summaryps
anames = sort $ nub $ map paccount ps anames = nubSort $ map paccount ps
-- aggregate balances by account, like ledgerFromJournal, then do depth-clipping -- aggregate balances by account, like ledgerFromJournal, then do depth-clipping
accts = accountsFromPostings ps accts = accountsFromPostings ps
balance a = maybe nullmixedamt bal $ lookupAccount a accts balance a = maybe nullmixedamt bal $ lookupAccount a accts

View File

@ -46,7 +46,7 @@ where
import Control.Applicative ((<|>)) import Control.Applicative ((<|>))
import Data.Data (Data) import Data.Data (Data)
import Data.List import Data.List.Extra (nubSort)
import Data.Maybe import Data.Maybe
import qualified Data.Text as T import qualified Data.Text as T
import Data.Typeable (Typeable) import Data.Typeable (Typeable)
@ -337,7 +337,7 @@ simplifyStatuses l
| length l' >= numstatuses = [] | length l' >= numstatuses = []
| otherwise = l' | otherwise = l'
where where
l' = nub $ sort l l' = nubSort l
numstatuses = length [minBound .. maxBound :: Status] numstatuses = length [minBound .. maxBound :: Status]
-- | Add/remove this status from the status list. Used by hledger-ui. -- | Add/remove this status from the status list. Used by hledger-ui.

View File

@ -22,6 +22,7 @@ module Hledger.Reports.TransactionsReport (
where where
import Data.List import Data.List
import Data.List.Extra (nubSort)
import Data.Ord import Data.Ord
import Hledger.Data import Hledger.Data
@ -79,7 +80,7 @@ transactionsReportByCommodity tr =
[(c, filterTransactionsReportByCommodity c tr) | c <- transactionsReportCommodities tr] [(c, filterTransactionsReportByCommodity c tr) | c <- transactionsReportCommodities tr]
where where
transactionsReportCommodities (_,items) = transactionsReportCommodities (_,items) =
nub $ sort $ map acommodity $ concatMap (amounts . triAmount) items nubSort . map acommodity $ concatMap (amounts . triAmount) items
-- Remove transaction report items and item amount (and running -- Remove transaction report items and item amount (and running
-- balance amount) components that don't involve the specified -- balance amount) components that don't involve the specified

View File

@ -21,6 +21,7 @@ import Data.Default (def)
#endif #endif
-- import Data.Monoid -- -- import Data.Monoid --
import Data.List import Data.List
import Data.List.Extra (nubSort)
import Data.Maybe import Data.Maybe
-- import Data.Text (Text) -- import Data.Text (Text)
import qualified Data.Text as T import qualified Data.Text as T
@ -205,7 +206,7 @@ runBrickUi uopts@UIOpts{cliopts_=copts@CliOpts{inputopts_=_iopts,reportopts_=rop
withManager $ \mgr -> do withManager $ \mgr -> do
dbg1IO "fsnotify using polling ?" $ isPollingManager mgr dbg1IO "fsnotify using polling ?" $ isPollingManager mgr
files <- mapM (canonicalizePath . fst) $ jfiles j files <- mapM (canonicalizePath . fst) $ jfiles j
let directories = nub $ sort $ map takeDirectory files let directories = nubSort $ map takeDirectory files
dbg1IO "files" files dbg1IO "files" files
dbg1IO "directories to watch" directories dbg1IO "directories to watch" directories

View File

@ -74,6 +74,7 @@ executable hledger-ui
, containers , containers
, data-default , data-default
, directory , directory
, extra >=1.6.3
, filepath , filepath
, fsnotify >=0.2.1.2 && <0.4 , fsnotify >=0.2.1.2 && <0.4
, hledger >=1.16.1 && <1.17 , hledger >=1.16.1 && <1.17

View File

@ -50,6 +50,7 @@ dependencies:
- containers - containers
- data-default - data-default
- directory - directory
- extra >=1.6.3
- filepath - filepath
- fsnotify >=0.2.1.2 && <0.4 - fsnotify >=0.2.1.2 && <0.4
- microlens >=0.4 - microlens >=0.4

View File

@ -13,7 +13,8 @@ module Hledger.Web.Widget.AddForm
import Control.Monad.State.Strict (evalStateT) import Control.Monad.State.Strict (evalStateT)
import Data.Bifunctor (first) import Data.Bifunctor (first)
import Data.List (dropWhileEnd, intercalate, nub, sort, unfoldr) import Data.List (dropWhileEnd, intercalate, unfoldr)
import Data.List.Extra (nubSort)
import Data.Maybe (isJust) import Data.Maybe (isJust)
#if !(MIN_VERSION_base(4,13,0)) #if !(MIN_VERSION_base(4,13,0))
import Data.Semigroup ((<>)) import Data.Semigroup ((<>))
@ -71,7 +72,7 @@ addForm j today = identifyForm "add" $ \extra -> do
let (postRes, displayRows) = validatePostings acctRes amtRes let (postRes, displayRows) = validatePostings acctRes amtRes
-- bindings used in add-form.hamlet -- bindings used in add-form.hamlet
let descriptions = sort $ nub $ tdescription <$> jtxns j let descriptions = nubSort $ tdescription <$> jtxns j
journals = fst <$> jfiles j journals = fst <$> jfiles j
pure (validateTransaction dateRes descRes postRes, $(widgetFile "add-form")) pure (validateTransaction dateRes descRes postRes, $(widgetFile "add-form"))

View File

@ -166,6 +166,7 @@ library
, containers , containers
, data-default , data-default
, directory , directory
, extra >=1.6.3
, filepath , filepath
, hjsmin , hjsmin
, hledger >=1.16.1 && <1.17 , hledger >=1.16.1 && <1.17

View File

@ -112,6 +112,7 @@ library:
- data-default - data-default
- Decimal - Decimal
- directory - directory
- extra >=1.6.3
- filepath - filepath
- hjsmin - hjsmin
- http-conduit - http-conduit

View File

@ -75,6 +75,7 @@ import Data.Char
import Data.Default import Data.Default
import Data.Functor.Identity (Identity) import Data.Functor.Identity (Identity)
import "base-compat-batteries" Data.List.Compat import "base-compat-batteries" Data.List.Compat
import Data.List.Extra (nubSort)
import Data.List.Split (splitOneOf) import Data.List.Split (splitOneOf)
import Data.Ord import Data.Ord
import Data.Maybe import Data.Maybe
@ -661,7 +662,7 @@ likelyExecutablesInPath :: IO [String]
likelyExecutablesInPath = do likelyExecutablesInPath = do
pathdirs <- splitOneOf "[:;]" `fmap` getEnvSafe "PATH" pathdirs <- splitOneOf "[:;]" `fmap` getEnvSafe "PATH"
pathfiles <- concat `fmap` mapM getDirectoryContentsSafe pathdirs pathfiles <- concat `fmap` mapM getDirectoryContentsSafe pathdirs
return $ nub $ sort pathfiles return $ nubSort pathfiles
-- exclude directories and files without execute permission. -- exclude directories and files without execute permission.
-- These will do a stat for each hledger-*, probably ok. -- These will do a stat for each hledger-*, probably ok.
-- But they need paths, not just filenames -- But they need paths, not just filenames

View File

@ -8,6 +8,7 @@ where
import Data.Function import Data.Function
import Data.List import Data.List
import Data.List.Extra (nubSort)
import qualified Data.Text as T import qualified Data.Text as T
import Hledger import Hledger
import Hledger.Cli.CliOptions import Hledger.Cli.CliOptions
@ -28,7 +29,7 @@ accountsNames :: Journal -> [(String, AccountName)]
accountsNames j = map leafAndAccountName as accountsNames j = map leafAndAccountName as
where leafAndAccountName a = (T.unpack $ accountLeafName a, a) where leafAndAccountName a = (T.unpack $ accountLeafName a, a)
ps = journalPostings j ps = journalPostings j
as = nub $ sort $ map paccount ps as = nubSort $ map paccount ps
checkdupes' :: (Ord k, Eq k) => [(k, v)] -> [(k, [v])] checkdupes' :: (Ord k, Eq k) => [(k, v)] -> [(k, [v])]
checkdupes' l = zip dupLeafs dupAccountNames checkdupes' l = zip dupLeafs dupAccountNames

View File

@ -13,7 +13,7 @@ module Hledger.Cli.Commands.Commodities (
) where ) where
import Control.Monad import Control.Monad
import Data.List import Data.List.Extra (nubSort)
import qualified Data.Map as M import qualified Data.Map as M
import qualified Data.Text.IO as T import qualified Data.Text.IO as T
@ -32,5 +32,5 @@ commoditiesmode = hledgerCommandMode
commodities :: CliOpts -> Journal -> IO () commodities :: CliOpts -> Journal -> IO ()
commodities _copts j = do commodities _copts j = do
let cs = filter (/= "AUTO") $ let cs = filter (/= "AUTO") $
nub $ sort $ M.keys (jcommodities j) ++ M.keys (jinferredcommodities j) nubSort $ M.keys (jcommodities j) ++ M.keys (jinferredcommodities j)
forM_ cs T.putStrLn forM_ cs T.putStrLn

View File

@ -14,7 +14,7 @@ module Hledger.Cli.Commands.Descriptions (
,descriptions ,descriptions
) where ) where
import Data.List import Data.List.Extra (nubSort)
import qualified Data.Text.IO as T import qualified Data.Text.IO as T
import Hledger import Hledger
@ -35,6 +35,6 @@ descriptions CliOpts{reportopts_=ropts} j = do
d <- getCurrentDay d <- getCurrentDay
let q = queryFromOpts d ropts let q = queryFromOpts d ropts
ts = entriesReport ropts q j ts = entriesReport ropts q j
descriptions = nub $ sort $ map tdescription ts descriptions = nubSort $ map tdescription ts
mapM_ T.putStrLn descriptions mapM_ T.putStrLn descriptions

View File

@ -15,7 +15,7 @@ module Hledger.Cli.Commands.Notes (
,notes ,notes
) where ) where
import Data.List import Data.List.Extra (nubSort)
import qualified Data.Text.IO as T import qualified Data.Text.IO as T
import Hledger import Hledger
@ -36,6 +36,6 @@ notes CliOpts{reportopts_=ropts} j = do
d <- getCurrentDay d <- getCurrentDay
let q = queryFromOpts d ropts let q = queryFromOpts d ropts
ts = entriesReport ropts q j ts = entriesReport ropts q j
notes = nub $ sort $ map transactionNote ts notes = nubSort $ map transactionNote ts
mapM_ T.putStrLn notes mapM_ T.putStrLn notes

View File

@ -15,7 +15,7 @@ module Hledger.Cli.Commands.Payees (
,payees ,payees
) where ) where
import Data.List import Data.List.Extra (nubSort)
import qualified Data.Text.IO as T import qualified Data.Text.IO as T
import Hledger import Hledger
@ -36,6 +36,6 @@ payees CliOpts{reportopts_=ropts} j = do
d <- getCurrentDay d <- getCurrentDay
let q = queryFromOpts d ropts let q = queryFromOpts d ropts
ts = entriesReport ropts q j ts = entriesReport ropts q j
payees = nub $ sort $ map transactionPayee ts payees = nubSort $ map transactionPayee ts
mapM_ T.putStrLn payees mapM_ T.putStrLn payees

View File

@ -6,7 +6,7 @@ module Hledger.Cli.Commands.Printunique (
) )
where where
import Data.List import Data.List.Extra (nubSortOn)
import Hledger import Hledger
import Hledger.Cli.CliOptions import Hledger.Cli.CliOptions
import Hledger.Cli.Commands.Print import Hledger.Cli.Commands.Print
@ -21,6 +21,6 @@ printuniquemode = hledgerCommandMode
printunique opts j@Journal{jtxns=ts} = do printunique opts j@Journal{jtxns=ts} = do
print' opts j{jtxns=uniquify ts} print' opts j{jtxns=uniquify ts}
where where
uniquify = nubBy (\t1 t2 -> thingToCompare t1 == thingToCompare t2) . sortOn thingToCompare uniquify = nubSortOn thingToCompare
thingToCompare = tdescription thingToCompare = tdescription
-- thingToCompare = tdate -- thingToCompare = tdate

View File

@ -14,6 +14,7 @@ module Hledger.Cli.Commands.Stats (
where where
import Data.List import Data.List
import Data.List.Extra (nubSort)
import Data.Maybe import Data.Maybe
import Data.Ord import Data.Ord
import Data.HashSet (size, fromList) import Data.HashSet (size, fromList)
@ -108,4 +109,4 @@ showLedgerStats l today span =
acctdepth | null as = 0 acctdepth | null as = 0
| otherwise = maximum $ map accountNameLevel as | otherwise = maximum $ map accountNameLevel as
mktprices = jpricedirectives j mktprices = jpricedirectives j
mktpricecommodities = nub $ sort $ map pdcommodity mktprices mktpricecommodities = nubSort $ map pdcommodity mktprices