Вы можете использовать метод Array#reduce
для достижения результата с дополнительным объектом для ведения счета.
export let findMode = (b: number[]): number => {
// object for keeping count of each element
// initially set `0` with 0 count (default value)
let ref = {
'0': 0
};
return b.reduce((value, num) => {
// define count as 0 if not defined
ref[num] = ref[num] || 0;
// increment element count
ref[num]++;
// if number count is gretater than previous element count
// then return current element
if (ref[num] > ref[value]) {
return num;
// if counts are same then return the smallest value
} else if (ref[num] === ref[value]) {
return num < value ? num : value;
}
// else return the previous value
return value;
// set initial value as 0(default)
}, 0);
};
let findMode = b => {
let ref = {
'0': 0
};
return b.reduce((value, num) => {
ref[num] = ref[num] || 0;
ref[num]++;
if (ref[num] > ref[value]) {
return num;
} else if (ref[num] === ref[value]) {
return num < value ? num : value;
}
return value;
}, 0);
};
[
[2, 1, 1, 2, 1, 0],
[1, 3, 2],
[0, 0, 0, 1, 1, 2, 1, 1],
[4, 4, 7, 4, 0, 7],
[-4, -4, -1, 3, 5],
[1, 1, 2, 3, 2],
[10, 10, 10, 20, 20, 30]
].forEach(v => console.log(findMode(v)))
Чтобы избежать использования повышения и реализовать Ваше собственное, можно смотреть на книгу http://en.wikipedia.org/wiki/Modern_C%2B%2B_Design
Существует библиотека Loki, описанная в книге с хорошим объяснением, как сделать Ваше собственное достаточно умное для Вашего функтора потребности.
class Dispather
{
public:
typedef boost::function< void ( void ) > FunctionT;
void Register( const std::string& name, FunctionT function )
{
registered_[ name ] = function;
}
void Call( const std::string& name )
{
RegisterdFunctionsT::const_iterator it =
registered_.find( name );
if ( it == registered_.end() )
throw std::logic_error( "Function is not registered" );
(it->second)();
}
private:
typedef std::map< std::string, FunctionT > RegisterdFunctionsT;
RegisterdFunctionsT registered_;
};
int main()
{
X x;
Y y;
Dispather d;
d.Register( "x", boost::bind( &X::MethodX, &x ) );
d.Register( "y", boost::bind( &Y::MethodY, &y ) );
d.Call( "x" );
d.Call( "y" );
return 0;
}
Смотрите на данную статью:
http://www.oopweb.com/CPP/Documents/FunctionPointers/Volume/CCPP/functor/functor.html
Это реализует основанный на шаблоне функтор в C++. пусто* используется под капотами, но это все безопасно с точки зрения типов, потому что это перенесено шаблонными функциями, которые создают и разворачивают void*. Это сделало бы реализацию этого легкой. Это поддерживает множество стилей вызова, которые простые указатели метода не делают (например, можно передать функцию, возвратив что-то как возврат функтора пусто, и это автоматически игнорирует возвращаемое значение),