Skip to content

Commit

Permalink
added test.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
sfinktah committed Oct 31, 2017
1 parent 60da170 commit ad693e6
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 41 deletions.
70 changes: 29 additions & 41 deletions lodash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,28 +361,21 @@ namespace _
auto k = i->first;
helper::add_to_container(result, k);
}
//for (auto i = container.begin(); i != container.end(); ++i)
//{
// helper::add_to_container(result, i->key());
//}
return result;
}

// sfink - keys2
template <typename Container, typename ResultContainer = Container::value_type>
ResultContainer keys2(Container container)
template <typename Container>
auto keys2(const Container& container)
{
ResultContainer result;
for (auto i = container.begin(); i != container.end(); ++i)
{
auto k = i->first;
helper::add_to_container(result, k);
}
return keys<std::vector<typename Container::key_type>>(container);
//typename Container::key_type result;
//for (auto i = container.begin(); i != container.end(); ++i)
//{
// helper::add_to_container(result, i->key());
// auto k = i->first;
// helper::add_to_container(result, k);
//}
return result;
//return result;
}

// MDN - The slice() method returns a shallow copy of a portion of an array into a
Expand Down Expand Up @@ -450,7 +443,7 @@ namespace _
/// TODO Implement initialValue as optional: "[Optional] Value to use as the first argument to the first call of the callback. If no initial value is supplied, the first element in the array will be used. Calling reduce on an empty array without an initial value is an error."
/// TODO Implement full range of functionality as described in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce?v=b
template <typename Container, typename Function, typename Memo>
Memo reduce(const Container container, Function function, Memo initialValue)
Memo reduce(const Container& container, Function function, Memo initialValue)
{
for (auto i = container.begin(); i != container.end(); ++i)
{
Expand All @@ -459,20 +452,20 @@ namespace _
return initialValue;
}

/// <summary>Applies a function against an accumulator and each element in the array-container (from left to right) to reduce it to a single value.</summary>
/// <summary>`reduce` for sequence containers with 4 argument callback</summary>
/// <param name="container">The container.</param>
/// <param name="function">The callback, callback(<paramref name="initialValue" />, currentValue)</param>
/// <param name="function">callback(<paramref name="initialValue" />, currentValue, currentIndex, <paramref name="container" />)</param>
/// <param name="initialValue">Value to use as the first argument to the first call of the callback.</param>
/// <returns>The value that results from the reduction.</returns>
/// <example><code>
/// std::vector v{ 1, 2, 3 };
/// cout << v.reduce([](accumulator, currentValue, currentIndex, container) {
/// return accumulator + "Index: "s + std::to_string(currentIndex) + " = "s + std::to_string(currentValue) + '\n';
/// }, std::string{});
/// </example></code>
/// std::vector<int> v{ 1, 2, 3 };
/// count << _::reduceArray(v, [](auto accumulator, auto currentValue, auto currentIndex, auto container) {
/// return accumulator + "Index: "s + std::to_string(currentIndex) + " = "s + std::to_string(currentValue) + '\n';
/// }, std::string{})
/// </example></code>
/// TODO Implement initialValue as optional: "[Optional] Value to use as the first argument to the first call of the callback. If no initial value is supplied, the first element in the array will be used. Calling reduce on an empty array without an initial value is an error."
template <typename Container, typename Function, typename Memo>
Memo reduce2(const Container container, Function function, Memo initialValue)
Memo reduceArray(const Container& container, Function function, Memo initialValue)
{
each_with_distance(container, [&](const typename Container::value_type& value, const size_t index) {
initialValue = function(initialValue, value, index, container);
Expand All @@ -481,48 +474,43 @@ namespace _
}


/// <summary>Applies a function against an accumulator and each element in the container (from left to right) to reduce it to a single value.</summary>
/// <summary>`reduce` for associative containers with 4 argument callback</summary>
/// <see cref="reduce" />
/// <seealso cref="reduceArray" />
/// <param name="container">The container.</param>
/// <param name="function">The callback, callback(<paramref name="initialValue" />, currentValue)</param>
/// <param name="function">callback(<paramref name="initialValue" />, currentValue, currentKey, <paramref name="container" />)</param>
/// <param name="initialValue">Value to use as the first argument to the first call of the callback.</param>
/// <returns>The value that results from the reduction.</returns>
/// <example><code>
/// std::vector v{ 1, 2, 3 };
/// cout << v.reduce([](accumulator, currentValue, currentIndex, container) {
/// return accumulator + "Index: "s + std::to_string(currentIndex) + " = "s + std::to_string(currentValue) + '\n';
/// }, std::string{});
/// </example></code>
/// TODO Implement initialValue as optional: "[Optional] Value to use as the first argument to the first call of the callback. If no initial value is supplied, the first element in the array will be used. Calling reduce on an empty array without an initial value is an error."
template <typename Container, typename Function, typename Memo>
Memo reduceMap(const Container container, Function function, Memo initialValue)
Memo reduceObject(const Container& container, Function function, Memo initialValue)
{
// ResultContainer result;
auto keys = _::keys(container);
auto keys = _::keys2(container);
for (const auto& key : keys)
{
initialValue = function(initialValue, container[key], key, container);
// const auto& value = container.at(key);
auto value = container.at(key);
initialValue = function(initialValue, value, key, container);
}
return initialValue;
}
//for (auto i = container.begin(); i != container.end(); ++i) {
// function(*i, std::distance(container.begin(), i));
//}

template <typename Container, typename Function, typename Memo>
Memo inject(const Container container, Function function, Memo initialValue)
Memo inject(const Container& container, Function function, Memo initialValue)
{
return reduce(container, function, initialValue);
}

template <typename Container, typename Function, typename Memo>
Memo foldl(const Container container, Function function, Memo initialValue)
Memo foldl(const Container& container, Function function, Memo initialValue)
{
return reduce(container, function, initialValue);
}

// reduce_right/foldr
template <typename Container, typename Function, typename Memo>
Memo reduce_right(const Container container, Function function, Memo initialValue)
Memo reduce_right(const Container& container, Function function, Memo initialValue)
{
for (typename Container::const_reverse_iterator i = container.rbegin(); i != container.rend();
++i)
Expand All @@ -533,7 +521,7 @@ namespace _
}

template <typename Container, typename Function, typename Memo>
Memo foldr(const Container container, Function function, Memo initialValue)
Memo foldr(const Container& container, Function function, Memo initialValue)
{
return reduce_right(container, function, initialValue);
}
Expand Down
122 changes: 122 additions & 0 deletions test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// #include <algorithm>
// #include <array>
// #include <cctype>
// #include <cfloat>
// #include <climits>
// #include <cmath>
// #include <cstdarg>
// #include <cstdio>
// #include <cstdlib>
// #include <cstring>
// #include <ctime>
// #include <fstream>
// #include <functional>
// #include <iomanip>
// #include <iosfwd>
#include <iostream>
// #include <limits>
#include <map>
// #include <memory>
// #include <mutex>
#include <ostream>
// #include <queue>
// #include <random>
// #include <regex>
// #include <set>
#include <sstream>
// #include <stdarg.h>
// #include <stdint.h>
// #include <stdio.h>
// #include <stdlib.h>
#include <string>
// #include <time.h>
// #include <type_traits>
// #include <unordered_map>
// #include <unordered_set>
#include <vector>

#include "lodash.hpp"
// #include "test/json.hpp"

using namespace std::string_literals;

#define TEST(NAME, ...) \
std::cout << "\n\n********\n" << #NAME << ":\n" << (__VA_ARGS__)();

template<typename T>
std::string join(const T& elements, const char* const separator) {
std::ostringstream os;

const char* _separator = "";
for (auto& item : elements) {
os << _separator << item;
_separator = separator;
}
return os.str();
}

int main(int argc, const char** argv) {

// instead, you could also write (which looks very similar to the JSON above)
// json object = {
// {"pi", 3.141},
// {"happy", true},
// {"name", "Niels"},
// {"nothing", nullptr},
// {"answer", {
// {"everything", 42}
// }},
// {"list", {1, 0, 2}},
// {"object", {
// {"currency", "USD"},
// {"value", 42.99}
// }}
// };

TEST(reduceArray, []{
std::vector<int> v{ 1, 2, 3 };
return
_::reduceArray(v, [](auto accumulator, auto currentValue, auto currentIndex, auto container) {
return accumulator + "Index: "s + std::to_string(currentIndex) + " = "s + std::to_string(currentValue) + '\n';
}, "Output: "s);
});

TEST(keys, [&]{
std::map<std::string, int> m = {
{"a", 1},
{"b", 2},
{"c", 3}
};
return join(_::keys<std::vector<std::string>>(m), ", ");
});
TEST(keys2, [&]{
std::map<std::string, int> m = {
{"a", 1},
{"b", 2},
{"c", 3}
};
return join(_::keys2(m), ", ");
});
TEST(reduceObject, [&]{
std::map<std::string, int> m = {
{"a", 1},
{"b", 2},
{"c", 3}
};
return
_::reduceObject(m, [](
auto accumulator,
const auto& currentValue,
const auto& currentKey,
const auto& container)
{
return accumulator
+ "Key: "s
+ currentKey
+ " = "s
+ std::to_string(currentValue)
+ '\n'
;
}, "Output: "s);
});
}

0 comments on commit ad693e6

Please sign in to comment.