If you consider your list as a “data set” or “table” and consider each element in the list as a “row” and determine the data type of the elements as an enumeration of “attributes”, then what you get is a kind of “projection” in the sense of relational algebra : https://en.wikipedia.org/wiki/Projection_(relational_algebra) .
Here is an example of a Scala -example that senses multiple SQLs:
case class Row(id: Int, name: String, surname: String, age: Int) val data = List( Row(0, "Bob", "Smith", 25), Row(1, "Charles", "Miller", 35), Row(2, "Drew", "Shephard", 45), Row(3, "Evan", "Bishop", 55) ) val surnames = data map (_.surname) val ages = data map (_.age) val selectIdName = data map { row => (row.id, row.name) } println(surnames)
Here _.fieldName is a short syntax for a string literal of a function of type Row => TypeOfTheField .
In Haskell, this is somewhat trivial because declaring a record data type automatically puts all getter functions in scope:
data Row = Row { id :: Int , name :: String , surname :: String , age :: Int } deriving Show main = let dataset = [ Row 0 "Bob" "Smith" 25 , Row 1 "Charles" "Miller" 35 , Row 2 "Drew" "Shephard" 45 , Row 3 "Evan" "Bishop" 55 ] in print $ map name dataset -- prints ["Bob","Charles","Drew","Evan"]
Even Java has something similar since version 8:
import java.util.*; import java.util.stream.*; import static java.util.stream.Collectors.*; class JavaProjectionExample { private static class Row { private final int id; private final String name; private final String surname; private final int age; public Row(int id, String name, String surname, int age) { super(); this.id = id; this.name = name; this.surname = surname; this.age = age; } public int getId() { return this.id; } public String getName() { return this.name; } public String getSurname() { return this.surname; } public int getAge() { return this.age; } } public static void main(String[] args) { List<Row> data = Arrays.asList( new Row(0, "Bob", "Smith", 25), new Row(1, "Charles", "Miller", 35), new Row(2, "Drew", "Shephard", 45), new Row(3, "Evan", "Bishop", 55) ); List<Integer> ids = data.stream().map(Row::getId).collect(toList()); List<String> names = data.stream().map(Row::getName).collect(toList()); System.out.println(ids); System.out.println(names); } }
Here Row::getterName is a special syntax for getter methods, it is a value of type Function<Row, FieldType> .