mirror of https://github.com/Icinga/icinga2.git
Add map/reduce and filter functionality for the Array class
fixes #12247
This commit is contained in:
parent
0d02b01c02
commit
a3815e4efd
|
@ -692,6 +692,43 @@ Signature:
|
|||
|
||||
Returns a new array with all elements of the current array in reverse order.
|
||||
|
||||
### <a id="array-map"></a> Array#map
|
||||
|
||||
Signature:
|
||||
|
||||
function map(func);
|
||||
|
||||
Calls `func(element)` for each of the elements in the array and returns
|
||||
a new array containing the return values of these function calls.
|
||||
|
||||
### <a id="array-reduce"></a> Array#reduce
|
||||
|
||||
Signature:
|
||||
|
||||
function reduce(func);
|
||||
|
||||
Reduces the elements of the array into a single value by calling the provided
|
||||
function `func` as `func(a, b)` repeatedly where `a` is the previous result of
|
||||
function call (null initially) and `b` is an element of the array.
|
||||
|
||||
### <a id="array-filter"> Array#filter
|
||||
|
||||
Signature:
|
||||
|
||||
function filter(func);
|
||||
|
||||
Returns a copy of the array containing only the elements for which `func(element)`
|
||||
is true.
|
||||
|
||||
### <a id="array-filter"> Array#unique
|
||||
|
||||
Signature:
|
||||
|
||||
function unique();
|
||||
|
||||
Returns a copy of the array with all duplicate elements removed. The original order
|
||||
of the array is not preserved.
|
||||
|
||||
## <a id="dictionary-type"></a> Dictionary type
|
||||
|
||||
Inherits methods from the [Object type](19-library-reference.md#object-type).
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "base/functionwrapper.hpp"
|
||||
#include "base/scriptframe.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
@ -94,6 +95,11 @@ static Array::Ptr ArraySort(const std::vector<Value>& args)
|
|||
ObjectLock olock(arr);
|
||||
std::sort(arr->Begin(), arr->End());
|
||||
} else {
|
||||
Function::Ptr function = args[0];
|
||||
|
||||
if (vframe->Sandboxed && !function->IsSideEffectFree())
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Sort function must be side-effect free."));
|
||||
|
||||
ObjectLock olock(arr);
|
||||
std::sort(arr->Begin(), arr->End(), boost::bind(ArraySortCmp, args[0], _1, _2));
|
||||
}
|
||||
|
@ -137,6 +143,86 @@ static Array::Ptr ArrayReverse(void)
|
|||
return self->Reverse();
|
||||
}
|
||||
|
||||
static Array::Ptr ArrayMap(const Function::Ptr& function)
|
||||
{
|
||||
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
|
||||
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
|
||||
|
||||
if (vframe->Sandboxed && !function->IsSideEffectFree())
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Map function must be side-effect free."));
|
||||
|
||||
Array::Ptr result = new Array();
|
||||
|
||||
ObjectLock olock(self);
|
||||
BOOST_FOREACH(const Value& item, self) {
|
||||
ScriptFrame uframe;
|
||||
std::vector<Value> args;
|
||||
args.push_back(item);
|
||||
result->Add(function->Invoke(args));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Value ArrayReduce(const Function::Ptr& function)
|
||||
{
|
||||
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
|
||||
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
|
||||
|
||||
if (vframe->Sandboxed && !function->IsSideEffectFree())
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Reduce function must be side-effect free."));
|
||||
|
||||
Value result;
|
||||
|
||||
ObjectLock olock(self);
|
||||
BOOST_FOREACH(const Value& item, self) {
|
||||
ScriptFrame uframe;
|
||||
std::vector<Value> args;
|
||||
args.push_back(result);
|
||||
args.push_back(item);
|
||||
result = function->Invoke(args);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Array::Ptr ArrayFilter(const Function::Ptr& function)
|
||||
{
|
||||
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
|
||||
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
|
||||
|
||||
if (vframe->Sandboxed && !function->IsSideEffectFree())
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Filter function must be side-effect free."));
|
||||
|
||||
Array::Ptr result = new Array();
|
||||
|
||||
ObjectLock olock(self);
|
||||
BOOST_FOREACH(const Value& item, self) {
|
||||
ScriptFrame uframe;
|
||||
std::vector<Value> args;
|
||||
args.push_back(item);
|
||||
if (function->Invoke(args))
|
||||
result->Add(item);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Array::Ptr ArrayUnique(void)
|
||||
{
|
||||
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
|
||||
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
|
||||
|
||||
std::set<Value> result;
|
||||
|
||||
ObjectLock olock(self);
|
||||
BOOST_FOREACH(const Value& item, self) {
|
||||
result.insert(item);
|
||||
}
|
||||
|
||||
return Array::FromSet(result);
|
||||
}
|
||||
|
||||
Object::Ptr Array::GetPrototype(void)
|
||||
{
|
||||
static Dictionary::Ptr prototype;
|
||||
|
@ -154,6 +240,10 @@ Object::Ptr Array::GetPrototype(void)
|
|||
prototype->Set("shallow_clone", new Function(WrapFunction(ArrayShallowClone), true));
|
||||
prototype->Set("join", new Function(WrapFunction(ArrayJoin), true));
|
||||
prototype->Set("reverse", new Function(WrapFunction(ArrayReverse), true));
|
||||
prototype->Set("map", new Function(WrapFunction(ArrayMap), true));
|
||||
prototype->Set("reduce", new Function(WrapFunction(ArrayReduce), true));
|
||||
prototype->Set("filter", new Function(WrapFunction(ArrayFilter), true));
|
||||
prototype->Set("unique", new Function(WrapFunction(ArrayUnique), true));
|
||||
}
|
||||
|
||||
return prototype;
|
||||
|
|
|
@ -118,6 +118,15 @@ public:
|
|||
return std::set<T>(Begin(), End());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static Array::Ptr FromSet(const std::set<T>& v)
|
||||
{
|
||||
Array::Ptr result = new Array();
|
||||
ObjectLock olock(result);
|
||||
std::copy(v.begin(), v.end(), std::back_inserter(result->m_Data));
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual Object::Ptr Clone(void) const override;
|
||||
|
||||
Array::Ptr Reverse(void) const;
|
||||
|
|
Loading…
Reference in New Issue