*vital/Data/Counter.txt*	Counter library to support convenient tallies.

Maintainer: haya14busa <hayabusa1419@gmail.com>

==============================================================================
CONTENTS				*Vital.Data.Counter-contents*

INTRODUCTION			|Vital.Data.Counter-introduction|
TERM				|Vital.Data.Counter-term|
INTERFACE			|Vital.Data.Counter-interface|
  FUNCTIONS			|Vital.Data.Counter-functions|
OBJECTS				|Vital.Data.Counter-objects|
  Counter Object		  |Vital.Data.Counter-Counter|

==============================================================================
INTRODUCTION				*Vital.Data.Counter-introduction*

*Vital.Data.Counter* is a counter library to support convenient tallies.

>
	let s:V = vital#{plugin-name}#new()
	let s:Counter = s:V.import('Data.Counter')
	let s:Math = s:V.import('Math')

	" count elements from a string
	let s:c = s:Counter.new('abcdeabcdabcaba')

	echo s:c.to_dict()
	" => {'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1}

	" three most common elements
	echo s:c.most_common(3)
	" => [['a', 5], ['b', 4], ['c', 3]]

	" list all unique elements
	echo sort(s:c.to_list())
	" => ['a', 'b', 'c', 'd', 'e']

	" list elements with repetitions
	echo join(sort(s:c.elements()), '')
	" => aaaaabbbbcccdde

	" total of all counts
	echo s:Math.sum(s:c.values())
	" => 15

	" count of letter 'a'
	echo s:c.get('a')
	" => 5

	" add counts from list
	call s:c.add(['s', 'h', 'a', 'z', 'a', 'm'])

	" now there are seven 'a'
	echo s:c.get('a')
	" => 7

	" remove all 'b'
	call s:c.del('b')

	" now there are zero 'b'
	echo s:c.get('b')
	" => 0
<
==============================================================================
TERM					*Vital.Data.Counter-term*

{countable}				*Vital.Data.Counter-term-countable*
	A {countable} is one of the followings.
	- |String|
	- |List|
	- {count-dict} |Vital.Data.Counter-term-count-dict|
	- {Counter} |Vital.Data.Counter-term-Counter|

{count-dict}				*Vital.Data.Counter-term-count-dict*
	A {count-dict} is |Dictionary| whose value is |Number|.
	e.g. {'a': 1, 'b': 2, 'c': 3}

{Counter}				*Vital.Data.Counter-term-Counter*
	A {Counter} is Counter Object |Vital.Data.Counter-Counter|.

==============================================================================
INTERFACE				*Vital.Data.Counter-interface*
------------------------------------------------------------------------------
FUNCTIONS				*Vital.Data.Counter-functions*

new([{countable}])			*Vital.Data.Counter.new()*
	Return a new 'Counter' object.

==============================================================================
OBJECTS					*Vital.Data.Counter-objects*

------------------------------------------------------------------------------
Counter Object			*Vital.Data.Counter-Counter*

Counter.get({key})		*Vital.Data.Counter-Counter.get()*
	Get count of {key} from Counter. Return 0 if {key} is not in the
	Counter.
>
	let s:c = s:Counter.new('vim')
	echo s:c.get('v')
	" => 1
	echo s:c.get('b')
	" => 0
<
Counter.set({key}, {nr})		*Vital.Data.Counter-Counter.set()*
	Set count of {key} to {nr}.
>
	let s:c = s:Counter.new('vim')
	call s:c.set('v', 3)
	call s:c.get('v')
	" => 3
<
Counter.add({countable})	*Vital.Data.Counter-Counter.add()*
	Adds counts from countable instead of replacing them.
>
	let s:c = s:Counter.new('vim')
	call s:c.add('vital')
	echo s:c.get('v')
	" => 2
<
Counter.subtract({countable})	*Vital.Data.Counter-Counter.subtract()*
	Subtracts count from countable. Counts can be reduced below zero. Both
	the inputs and outputs are allowed to contain zero and negative
	counts.
>
	let s:c = s:Counter.new('vim')
	call s:c.subtract('vital')
	echo s:c.get('v')
	" => 0
	echo s:c.get('a')
	" => -1
<
Counter.union({expr})		*Vital.Data.Counter-Counter.union()*
	{expr} is {Counter} or {count-dict}.  Returns a counter of the maximum
	of value in either of the input counters. It keeps only positive
	counts. It is non-destructive method, it doesn't change the counter
	nor an argument.
>
	let s:c = s:Counter.new('vim')
	echo s:c.union('vital').to_dict()
	" => {'a': 1, 't': 1, 'v': 1, 'i': 1, 'l': 1, 'm': 1}
<
Counter.intersection({expr})	*Vital.Data.Counter-Counter.intersection()*
	{expr} is {Counter} or {count-dict}.  Returns a counter of the maximum
	of value in either of the input counters. It keeps only positive
	counts. It is non-destructive method, it doesn't change the counter
	nor an argument.
>
	let s:c = s:Counter.new('vim')
	echo s:c.intersection('vital').to_dict()
	" => {'v': 1, 'i': 1}
<
Counter.clear()			*Vital.Data.Counter-Counter.clear()*
	Reset all counts.
>
	let s:c = s:Counter.new('vim')
	call s:c.clear()
	echo s:c.get('v')
	" => 0
<
Counter.elements()		*Vital.Data.Counter-Counter.elements()*
	Returns a list of elements repeating each as many times as its count.
	Elements are returned in arbitrary order. If an element's count is
	less than one, elements() will ignore it.
>
	let s:c = s:Counter.new('ABCABC')
	echo sort(s:c.elements())
	" => ['A', 'A', 'B', 'B', 'C', 'C']
<
Counter.most_common({nr})	*Vital.Data.Counter-Counter.most_common()*
	Returns a list of the {nr} most common elements and their counts
	from the most common to the least. If n is omitted, most_common()
	returns all elements in the counter. Elements with equal counts are
	ordered arbitrarily.
>
	echo s:Counter.new('abcdeabcdabcaba').most_common(3)
	" => [['a', 5], ['b', 4], ['c', 3]]
<
Counter.to_dict()		*Vital.Data.Counter-Counter.to_dict()*
	Returns {count-dict} |Vital.Data.Counter-term-count-dict| from Counter
	object.
>
	let s:c = s:Counter.new('ABCABC')
	echo s:c.to_dict()
	" => {'A': 2, 'B': 2, 'C': 2}
<
Counter.to_list()		*Vital.Data.Counter-Counter.to_list()*
	Returns list of element in the counter. The order is arbitrary.
>
	let s:c = s:Counter.new('ABCABC')
	echo sort(s:c.to_list())
	" => ['A', 'B', 'C']
<
Counter.values()		*Vital.Data.Counter-Counter.values()*
	Returns list of count in the counter. The order is arbitrary.
>
	let s:c = s:Counter.new('ABCABC')
	echo sort(s:c.values())
	" => [2, 2, 2]
<
Counter.in({expr})		*Vital.Data.Counter-Counter.in()*
	Returns the Number 1 if the given element is in the counter, zero
	otherwise.
>
	let s:c = s:Counter.new('ABCABC')
	echo s:c.in('A')
	" => 1
	echo s:c.in('D')
	" => 0
<
Counter.del({expr})		*Vital.Data.Counter-Counter.del()*
	Deletes the given element from the counter. Does not raise error for
	missing values.
>
	let s:c = s:Counter.new('ABCABC')
	call s:c.del('A')
	echo s:c.in('A')
	" => 0
<
Counter.keep_positive()		*Vital.Data.Counter-Counter.keep_positive()*
	Strips elements with a negative or zero count. This is similar to
	unary addition to collections.Counter in python.
>
        let c = s:Counter.new({'A': 2, 'B': -1, 'C': 0})
        call c.keep_positive()
        echo c.to_dict()
        " => {'A': 2}
<
Counter.reverse()		*Vital.Data.Counter-Counter.reverse()*
	Reverses the sign of counts.
>
        let c = s:Counter.new({'A': 2, 'B': -1, 'C': 0})
        call c.reverse()
        echo c.to_dict()
        " => {'A': -2, 'B': 1, 'C': 0}
<
==============================================================================
vim:tw=78:fo=tcq2mM:ts=8:ft=help:norl
