Skip to content
Daniel Meyer edited this page Jul 10, 2014 · 5 revisions

Filter / map

Java

With a map function:

Set<String> names = S("...")
  .xpath("/customer")
  .map(new Mapper<String>() {
    public String map(Spin s) {
      return s.attribute("name");
    }
  });

Without a map function:

Set<String> names = new HashSet<String>();
for(Spin customer : S("...").xpath("/customer")) {
  names.add(customer.attribute("name"));
}

A simple filter / map pipeline:

List<String> customerNames = S(xmlString)
  .xpath("/customer")
  .filter(new Filter() {
    public boolean filter(Spin s) {
      return s.attribute("rating").asInt() > 100;
    }
  }).map(new Mapper<String>() {
    public String map(Spin s) {
      return s.attribute("name");
    }
  });

We could also provide a set of default mappers for attributes etc.:

List<Integer> ratings = S(xmlString).map(attribute("rating", asInt()));

Async

S(inputStream, jsonStream()) // process large json file in streaming mode
  .jsonPath("customers.customer")  // for each customer in the stream
  .asyncMap(5, 10, new AsyncMapper<SpinJsonStreamObject, Integer>(SpinJsonStreamObject object, AsyncStremContext<SpinJsonStreamObject> streamCtx) {
    // 5 = number of threads, 10 = queue size
    
    // do something with the object (calculate score using BPMN process)
    try {

      Map<String, Object> pv = Collections.<String,Object>singletonMap("customer", object);
      pv = processEngine.getRuntimeService.startProcessInstanceByKey("customerScoringProcess", pv);

      SpinJsonStreamObject result = JSON("{}");
      result.prop("customerId", object.prop("customerId"));
      result.prop("score", pv.get("score"));
      streamCtx.resolve(result);

    } catch(RuntimeException e) {
      streamCtx.error(...)
    }
  });

Python

highRatedCustomers = filter(lambda s: s.attribute('rating').asInt() > 100, S('...').xpath("/customer"))
highRatedCustomersNames = map(lambda s: s.attribute('name'), highRatedCustomers)
numberOfHighRatedCustomersWhereNameStartsWithA = len([name for name in highRatedCustomersNames if name.lower().startswith('a')])

or

def highRating(s):
  return s.attribute('rating') > 100

oneline = len([
  customer for customer in filter(highRating, S('...').xpath('/customer')) if customer.attribute('name').lower().startswith('a')
])

Transformers

Url-like syntax with query parameters

S( myJavaClass ).transformTo("data-format://json?dateFormat='YYYY-MM-dd'&indent");

Or a more "typed" approach

DataFormat json = JSON.config("dateFormat", "YYYY-MM-dd").config("indent");
DataFormat json = JSON.dateFormat("YYYY-MM-dd").indent();

S( myJavaClass ).transformTo(json);
Clone this wiki locally