This is the 22nd day of my participation in the August Wen Challenge.More challenges in August

seq.not_any

Seq.not_any (seq, fn) and seq.every are reversed, returning true if and only if fn(x) == false for every element in seq, and false for all others, indicating that no element in seq satisfies the particular predicate check:

## seq.not_any
println("There are not any elements in array is less than zero: " 
        + seq.not_any(a, lambda(x) -> x < 0 end));
println("There are not any  in range is less than zero: " 
        + seq.not_any(r, lambda(x) -> x < 0 end));
Copy the code
There are not any elements in array is less than zero: true There are not any elements in range is less than zero: False #### seq.some seq.some(seq, fn) returns the first element in seq such that fn(x) == true, or nil if none is found:Copy the code

seq.some

println(“Find a element in array is greater than zero: ” + seq.some(a, lambda(x) -> x > 0 end)); println(“Find a element in range is greater than zero: ” + seq.some(r, lambda(x) -> x > 0 end)); println(“Find a element in list is starting with ‘c’: ” + seq.some(n, lambda(x) -> string.startsWith(x, “c”) end));

Copy the code

Find a element in array is greater than zero: 1 Find a element in range is greater than zero: 1 Find a element in list is starting with ‘c’: car

#### take_while 'take_while(sequence, pred)' is used to select the element from the sequence whose 'pred(element)' returns' true 'and return the new set:Copy the code

fn is_neg(x) { x < 0 }

let list = seq.list(-2, -1, 0, 1, 2, 3, 0, 99, -1000, 7); let result = take_while(list, is_neg); p(“result of take_while: #{result}”);

With 'take_while' we pick out all negative numbers from 'list' and print:Copy the code

result of take_while: [-2, -1, -1000]

Conversely, we can 'drop' all negative numbers using 'drop_while'. #### drop_whileCopy the code

let result = drop_while(list, is_neg);

p(“result of drop_while: #{result}”);

Drop all negative numbers from 'list'. The rest should be non-negative:Copy the code

result of drop_while: [0, 1, 2, 3, 0, 99, 7]

#### group_by 'group_by(sequence, keyfn)' can be used to group sets. It will apply the function 'keyfn' to each element in the set, return the group key, and then return the same key to the same list. Eventually return to a map mapping: ` {key1 - > [e1 and e2], key2 - > (e3 and e4),... } ` :Copy the code

let result = group_by(list, is_neg); p(“result of group_by: #{result}”);

Executing the code above prints:Copy the code

result of group_by: {false=[0, 1, 2, 3, 0, 99, 7], true=[-2, -1, -1000]}

'is_neg' returns true when negative numbers are encountered, false otherwise, so the final set becomes two groups. #### distinct 'DISTINCT (sequence)' is used to eliminate duplicate elements in a collection and return a collection without duplicates:Copy the code

let result = distinct(list); p(“result of distinct: #{result}”);

The outputCopy the code

result of distinct: [-2, -1, 0, 1, 2, 3, 99, -1000, 7]

You can see that the 0 repeating element is removed, leaving only one. #### reverse 'reverse(sequence)' is used to return the reverse result of a set, and only applies to sequential sets such as arrays and lists:Copy the code

let result = reverse(list); p(“result of reverse: #{result}”);

Prints a collection of inversions of list:Copy the code

list is: [-2, -1, 0, 1, 2, 3, 0, 99, -1000, 7] …… result of reverse: [7, -1000, 99, 0, 3, 2, 1, 0, -1, -2]

#### zipmap Next we will describe several functions used to generate sets, starting with 'zipmap(list1, list2)', which maps two sets into a single map in the order 'e1-> e2'. Let's look at an example:Copy the code

Let m = zipmap (tuple (” a “, “b”, “c”), seq. List (1, 2, 3, 4)); p(“type of m: ” + type(m)); p(“result of zipmap: #{m}”);

We pass in two collections to 'zipmap' and end up with a map:Copy the code

type of m: java.util.HashMap result of zipmap: {a=1, b=2, c=3}

If the two sets have different lengths, the shortest set is ended:Copy the code

Let m = zipmap (tuple (” a “, “b”, “c”), seq. List (1, 2, 3, 4, 5, 6)); p(“result of zipmap: #{m}”);

The result is still {a=1, b=2, c=3} '. #### concat 'concat(seQ1, seq2)' is used to join two sets to generate a new set with complexity in O(m+n) where m and n are the lengths of two sets respectively:Copy the code

let c = concat(tuple(“a”, “b”, “c”), seq.list(1, 2, 3, 4)); p(“result of concat: #{c}”);

Output:Copy the code

result of concat: [a, b, c, 1, 2, 3, 4]

Suppose you have a scenario where you get a java.sql.ResultSet from the User table in the database, and you want to pass it into AviatorScript to process it, and you want to use the various functions mentioned above. Then you can implement a SEQ wrapper for 'ResultSet' :Copy the code

package com.googlecode.aviator.example.seq;

import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import com.googlecode.aviator.runtime.type.Collector; import com.googlecode.aviator.runtime.type.Sequence; import com.googlecode.aviator.runtime.type.seq.ListCollector; import com.googlecode.aviator.utils.Reflector;

/ * *

*/ public class ResultSetSequence implements Sequence<Map<String, Object>> { private final ResultSet resultSet;

public ResultSetSequence(final ResultSet resultSet) { super(); this.resultSet = resultSet; }

@Override public Iterator<Map<String, Object>> iterator() { return new Iterator<Map<String, Object>>() {

@Override public boolean hasNext() { try { return ResultSetSequence.this.resultSet.next(); } catch (SQLException e) { throw Reflector.sneakyThrow(e); } } @Override public Map<String, Object> next() { try { Map<String, Object> user = new HashMap<>(); user.put("username", ResultSetSequence.this.resultSet.getString("username")); user.put("age", ResultSetSequence.this.resultSet.getString("age")); return user; } catch (SQLException e) { throw Reflector.sneakyThrow(e); } } @Override public void remove() { throw new UnsupportedOperationException(); }};Copy the code

}

@Override public Collector newCollector(final int size) { return new ListCollector(false); }

@Override public int hintSize() { // if we don’t known the exact row number, return 0. return 0; }

}

The core is the 'iterator' method, where we take the result of a row in 'next' and return it as a map object. You can then wrap this' ResultSet 'and throw it into AvaitorScript:Copy the code

package com.googlecode.aviator.example.seq;

import java.sql.ResultSet; import org.mockito.Mockito; import com.googlecode.aviator.AviatorEvaluator; import com.googlecode.aviator.Expression;

public class DemoResultSetSeq {

public static void main(final String[] args) throws Exception { // Mock a result set. ResultSet resultSet = Mockito.mock(ResultSet.class); Mockito.when(resultSet.next()).thenReturn(true).thenReturn(true).thenReturn(false); Mockito.when(resultSet.getString(“username”)).thenReturn(“dennis”).thenReturn(“catty”); Mockito.when(resultSet.getInt(“age”)).thenReturn(30).thenReturn(20);

// Use it in aviator
Expression exp = AviatorEvaluator.getInstance().compileScript("examples/result_set_seq.av");
exp.execute(exp.newEnv("results", new ResultSetSequence(resultSet)));
Copy the code

}}

We first used mockito to simulate a 'ResultSet', which will return two rows:Copy the code

username, age

dennis, 30 catty, 20

Then wrap the resultSet into 'ResultSetSequence' and pass it as the 'results' variable to the script' examples/result_set_seq.av ':Copy the code

examples/result_set_seq.av

let users = into(seq.list(), results);

println(“User names: “

  • map(users, lambda(u) -> u.username end));

println(“users that age is greater than 30: “

  • filter(users, lambda(u) -> u.age > 30 end));

println(“Total age: “

  • reduce(users, lambda(n, u) -> n + u.age end, 0));
We first use 'into' function to extract the results from 'ResultSet', which is convenient for subsequent operations. Next, we use Map to obtain the variable name list of users, filter users over 30 years old, and calculate the total age number by reduce:Copy the code

User names: [dennis, catty] users that age is greater than 30: [] Total age: 50

Copy the code