DataField.js — v0.3.0
Select, sort, filter and perform maths and analysis on your arrays of data
Zero-dependency Javascript library for Node and browsers that works with collections

Currently in early beta — code contributions are more than welcome
What is DataField

DataField is a library that helps you wrangle your awesome collections of data you obtain from different sources.

Imagine you are building a web application that deals with users. You make an API request and receive an array of 100 entries which look like this one below:

        
    {
      "_id": "5b420ae94fe6464ff91f5de8",
      "index": 0,
      "guid": "871eebf0-9983-4eb5-a0b5-59372a2fbecd",
      "isActive": true,
      "balance": "$1,268.06",
      "age": 41,
      "name": {
        "first": "Pearlie",
        "last": "Osborne"
      },
      "company": "PIVITOL",
      "email": "pearlie.osborne@pivitol.net",
      "phone": "+1 (992) 418-2307",
      "address": "190 River Street, Spelter, Tennessee, 1088",
      "registered": "Monday, April 18, 2016 7:35 AM",
      "tags": ["ad", "magna", "aliqua"],
      "friends": [{"id": 0, "name": "Whitney Snow"}, {"id": 1, "name": "Garza Hernandez"}, {"id": 2,"name": "Lourdes Conley"}]
    }
        
      

With this library it is rather easy to perform various actions on your data.

How It Works
const users = new DataField(arrayOfUsers)

Now your data is stored in an instance of DataField class.

Each method that does any kind of selection or filtering returns a new instance of DataField and can be chained.

Math methods return primitives and can not be chained

To extract your data use .values() or .toArray()

Now lets filter our data. We need users who are 30 years old or older, but not 41 years old and have at least 2 friends, but less than 10. Also we want our list sorted by last name in descending order. After that we are done so we want an array out of that:

users.where('age').gte(30).not(41).where('friends').range(2, 10).sort({by: 'name.last', order: 'desc'}).toArray()

Or you can go more object-oriented way (this one below is kinda weird request although):


users.where('age').any({
  range: [8, 88],
  lte: 18,
  gt: 60,
  not: 42,
  is: false
})
  .toArray()

That's it. API is short and simple. Look to the left – there is a list of methods.

Open console in your browser. There is a variable users there you can play with — it is a DataField instance with 100 entries in it.
Installation
npm:
npm i datafield

cdn:
https://unpkg.com/datafield@latest
API
Basic Operations. Filtering
.where(string)

Basic property selector. All subsequent operations will be based on this selector. If no selector present an error will be thrown

              
users.where('age').eq(30)
              
            

Nested properties can be selected using dot notation within a string

              
users.where('name.last').gte('B')
              
            

If you need to filter your data based on multiple properties you can chain them

              
users
    .where('age').gte(18)
    .where('isActive').isTruthy()
    .where('friends').range(2,20)
              
            
.values()

Unwraps DataField instance into an array. toArray() does the same job.

              users.toArray().map(user => user.age)
            
toArray()
Another syntax for values()
exists([property])

Selects entries where property exists. If no property value is passed then library tries to use the last selector

              
// this is okay:
users.where('email').exists()
// this is okay too:
users.exists('email')
// this will throw an error:
users.exists()
              
            
has(property)

Selects entries where property exists and has truthy value.

              
users.has('email').where('age').gte(18).median()
// selects users who have their email added to the profile, 18 years or older and return the age median of such users
              
            
take([number])

Returns Number entries from DataField object, starting from the first one. If value is not provided then returns one entry. If value is greater than amount of entries left - returns the rest of them

              
users.where('age').asc().take(10)
              
            
Important! History of take() is stored in an instance the method was called on. Consider the following:
              
const users = new DataField(data)  // 12 entries in an array
firstFive = users.take(5) // indices 0 - 4
SecondFive = users.take(5) // indices 5 - 9
restOfUsers = users.take(5) // indices 9 - end of array
              
            
takeRandom([Number])

Returns Number random entries from DataField object. If value is not provided then returns one entry. Unlike take() method does not track its own history

              
users.takeRandom() // returns one random entry
              
            
pick([String])

Returns entries from DataField object based filtered by arguments. If value is not provided then returns unchanged data set

Possible values — "even", "odd" or "{number}n" (i.e. "3n") — return new DataField of every other, every odd or every 3rd item respectively

              
users.pick("5n") // returns every 5th item in the data set
              
            
length

Getter. Returns the number of entries

              
users.length // 100
              
            
Comparison
eq(value)
not(value)
gt(value)
gte(value)
lt(value)
lte(value)

Selects entries by condition. Currently supports Number, String, Date values

              
users
    .where('age').eq(42)
    .where('registered').gte(new Date("Jan 1 2017")).lte(new Date("Dec 31 2018"))
    .where('company').not('COMVOY')
              
            
isTruthy()

Selects entries with truthy selector value (one that evaluates to true in Javascript)

              
users.where('isActive').isTruthy()
              
            
isFalsy()

Selects entries with falsy selector value (one that evaluates to false in Javascript)

              
users.where('isActive').isFalsy()
              
            
includes(value)

Selects entries which array selectors include value Works similar to ES7 includes

              
users.where('tags').includes('nostrud')
              
            
range(from, to)

Selects entries with selector's value within the given range.

Currently supports Number, String, Date, Array.length

              
const from = new Date("Feb 23 2014")
const to = new Date("May 12 2017")
users.where('registered').range(from, to)
              
            
Complex filtering
all(config)
any(config)

Selects entries based on configuration object.

.all() is an AND logic — entry must satisfy all conditions

.any() is an OR-like filter — entry must satisfy at least one condition

possible properties: gt, gte, lt, lte, eq, not, range, is

is
is a boolean condition same as isTruthy / isFalsy methods
range
value should be an array of with the length of 2 —
[from, to]
              
users.where('age').all({
  range: [16, 33],
  not: 27
})

users.where('age').any({
  is: false,
  eq: 42
})
            
Sorting
sort(config)

Sorts entries based on config options

Config:

              
{
  by: 'property', // <-- selector. MANDATORY
  order: 'asc' / 'desc' // <-- sorting order. OPTIONAL
  type: 'num' / 'str' / 'date' // type of value. OPTIONAL
}
              
            

If type is not provided library will try to guess it. If you want to sort by date make sure to explicitly add that to the config, otherwise it will be treated as a string

              
users.where('age').gte(18).sort({by: "name.last", order: "desc"})
              
            
asc()
desc()

Sorts by selector in ascending / descending order

              
users.where('company').asc()
// or
users.where('age').desc()
              
            
Math operations
sum(property, [strict])
avg(property, [strict])
median(property, [strict])

Returns a result of mathematical operation on. Ignored if selector is not of type Number. If strict parameter is set to false attempts to coerce types

              
users.where('isActive').isTruthy().sum('age') // 2083
users.where('isActive').isTruthy().sum('age', false) // 2107 – converted string to a number