---
# System prepended metadata

title: Question 1

---



# Question 1 

Given a hash, sanitize that hash ( remove "" elements, nil elements, [] elements ) 

Input
```
{
    k1: "v1",
    k2: ["v2", "v3", "", { k21: "v21", k22: "" }],
    k3: { k4: "v4", k5: ["v5", "v6", nil], k6: { k7: "v7", k8: "" } },
    k9: [[{}]],
    k10: nil,
    k11: [23, true, false, "hello"],
}
```

Output 
```
{
    "k1":"v1",
    "k2":["v2","v3",{"k21":"v21"}],
    "k3":{"k4":"v4","k5":["v5","v6"],"k6":{"k7":"v7"}},
    "k11":[23,true,false,"hello"]
}
```

#include <string>
#include <unordered_map>
#include <vector>
#include <utility>

using namespace std;

class MapValue {
	string stringValue = "";
	vector<MapValue> arrayValue = {};
	unordered_map<string, MapValue> nestedMapValue = {};
	bool boolValue = NULL;
	
	MapValue(const &string inputString) {
		stringValue = inputString;
	}
	MapValue(const &vector<MapValue> inputArray) {
		arrayValue = inputArray;
	}
	MapValue(const &unordered_map<string, MapValue> inputNestedMap) {
		nestedMapValue = inputNestedMap;
	}
	
	bool isStringValue() {
		return !stringValue.empty();
	}
	bool isArrayValue() {
		return !arrayValue.empty();
	}
	bool isNestedMapValue() {
		return !nestedMapValue.empty();
	}
	bool isBoolValue() {
		return (boolValue != NULL);
	}
	
	bool isEmptyObject() {
		return (stringValue.empty() && arrayValue.empty() 
			&& nestedMapValue.empty() && boolValue == NULL);
	}
}

MapValue sanitizeString(const string &input) {
	return new MapValue(input);
}

MapValue sanitizeArray(const vector<MapValue> &inputArray) {
	vector<MapValue> outputArray;
	for (auto &value : inputArray) {
		auto sanitizedValue = sanitizeMapValue(value);
		if (!sanitizedValue.isEmptyObject()) {
			outputArray.push_back(sanitizedValue);
		}
	}
	return new MapValue(outputArray);
}

MapValue sanitizeMap(const unordered_map<string, MapValue> &inputNestedMap) {
	unordered_map<string, MapValue> outputMap;
	for (auto &keyValuePair : input) {
		string key = keyValuePair.first;
		MapValue sanitizedValue = sanitizeMapValue(keyValuePair.second);
		if (!sanitizedValue.isEmptyObject()) {
			outputMap[key] = sanitizedValue;
		}
	}
	return new MapValue(outputMap);
}

MapValue sanitizeMapValue(const MapValue &mapValue) {
	if (mapValue.isStringValue()) {
		return sanitizeString(mapValue.stringValue);
	} else if (mapValue.isArrayValue()) {
		return sanitizeArray(mapValue.arrayValue);
	} else if (mapValue.isNestedMapValue()) {
		return sanitizeMap(mapValue.nestedMapValue);
	}
}

unordered_map<string, MapValue> sanitizeHash(const unordered_map<string, MapValue> &input) {
	sanitizeMap(input);
}

int main() {
	unordered_map<string, MapValue> input;
	
	MapValue value1 = new MapValue("v1");
	input["k1"] = value1;
	
	unordered_map<string, MapValue> nestedMap2 = {
		"k21": new MapValue("v21"),
		"k22": new MapValue("");
	};
	MapValue value2 = new MapValue((vector<MapValue>) {new MapValue("v2"), new MapValue("v3"), 
		new MapValue(""), new MapValue(nestedMap2),
	});
	input["k2"] = value2;
	
	auto &output = sanitizeHash(input);
	for (auto &keyValue : output) {
		cout << keyValue.first << ": " << keyValue.second << endl;
	}
	
	return 0;
}

/*
Input: 
{
    k1: "v1",
    k2: ["v2", "v3", "", { k21: "v21", k22: "" }],
    k3: { k4: "v4", k5: ["v5", "v6", nil], k6: { k7: "v7", k8: "" } },
    k9: [[{}]],
    k10: nil,
    k11: [23, true, false, "hello"],
}
Output: 
{
    "k1":"v1",
    "k2":["v2","v3",{"k21":"v21"}],
    "k3":{"k4":"v4","k5":["v5","v6"],"k6":{"k7":"v7"}},
    "k11":[23,true,false,"hello"]
}
*/
