Created
November 18, 2016 01:59
-
-
Save skritch/f19c1b1e52e02289d3ffb45d62ae201d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from itertools import imap | |
import json | |
class Map(object): | |
def __init__(self, iterable, steps=[]): | |
""" | |
Construct an iterator that looks up items in the given iterable by index, key, field name, or calls | |
a function on them. | |
:param iterable: An iterable of "objects" | |
""" | |
self.iterable = iterable | |
self.steps = steps | |
def from_existing(self, new_step): | |
steps = list(self.steps) + [new_step] | |
return Map(self.iterable, steps) | |
def __getattr__(self, name): | |
return self.from_existing(lambda i: getattr(i, name)) | |
def __getitem__(self, key): | |
return self.from_existing(lambda i: i[key]) | |
def get(self, key, default=None): | |
return self.from_existing(lambda i: self._get_even_from_list(i, key, default)) | |
def __or__(self, func): | |
return self.from_existing(func) | |
def __call__(self): | |
return list(self.__iter__()) | |
@staticmethod | |
def _get_even_from_list(obj, key, default=None): | |
if isinstance(obj, dict): | |
return obj.get(key, default) | |
try: | |
return obj[key] | |
except IndexError: | |
return default | |
def __repr__(self): | |
return "<MapGet({}) steps={}>".format(self.iterable, self.steps) | |
def __iter__(self): | |
return imap( | |
reduce( | |
lambda f, g: lambda x: g(f(x)), # function composition | |
self.steps, | |
lambda x: x # initializer | |
), | |
self.iterable | |
) | |
if __name__ == '__main__': | |
obj = [{"x":[{"y":{"z":5}}]}, {"x":[{"y":{"z":6}}]}] | |
m1 = Map(obj)["x"][0]["y"] | |
m2 = Map(m1) | |
print((m1 | json.dumps)()) | |
print((m2['z'] | (lambda x: x**2))()) | |
# ['{"z": 5}', '{"z": 6}'] | |
# [25, 36] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment