• Stars
    star
    105
  • Rank 328,196 (Top 7 %)
  • Language
    Erlang
  • License
    Other
  • Created almost 14 years ago
  • Updated about 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

KVC - Key Value Coding for Erlang data structures

KVC - Key Value Coding for Erlang data structures

[email protected]

Overview:

kvc supports Key Value Coding-like queries on common Erlang data structures. A common use case for kvc is to quickly access one or more deep values in decoded JSON, or some other nested data structure. It can also help with some aggregate operations. It solves similar problems that you might want to use a tool like XPath or jQuery for, but it is far simpler and strictly less powerful. It's inspired by Apple's NSKeyValueCoding protocol from Objective-C.

The following common Erlang data structures are supported:

  • list()
  • dict()
  • gb_trees()
  • proplist()
  • {struct, proplist()} (commonly used in mochijson2)
  • {proplist()} (EEP 18)
  • map() Erlang 17+

Only the following data types are permitted for keys, and they must be UTF-8 if any type coercion takes place:

  • atom()
  • binary()
  • string()

Another limitation is that it is assumed that the given data structure has a homogeneous key type. For example, if any key is binary(), all keys should be binary().

Collection Operators

The following collection operators are supported. Note that the numerics have straightforward implementations and no special care is taken reduce floating point error.

Their native representation is binary. Atom and string are also supported but require an additional type coercion for the look-up.

  • <<"@sum">>
  • <<"@min">>
  • <<"@max">>
  • <<"@count">>
  • <<"@avg">>
  • <<"@distinctUnionOfArrays">>
  • <<"@distinctUnionOfObjects">>
  • <<"@unionOfArrays">>
  • <<"@unionOfObjects">>

Status:

Not used in production, but it has a test suite that passes.

If you decide to use this in your production app, you should use lists for paths and try to use the same type as the keys in your data structure.

If you'd like to contribute to kvc, a good implementation for setters is the biggest missing piece.

Usage:

Two styles of queries are supported, the more performant native interface uses a list of keys for the path. If a string, binary, or atom are given then it will be split on '.' peroids to form this key list.

Simple proplist() example:

%% Native key list of atoms that match the data type (fastest)
wibble =:= kvc:path([foo, bar, baz], [{foo, [{bar, [{baz, wibble}]}]}]).

%% Native key list of binaries, does not match key data type (slower)
wibble =:= kvc:path([<<"foo">>, <<"bar">>, <<"baz">>],
                    [{foo, [{bar, [{baz, wibble}]}]}]).

%% These bare keys must be parsed first (slowest)
wibble =:= kvc:path('foo.bar.baz', [{foo, [{bar, [{baz, wibble}]}]}]).
wibble =:= kvc:path(<<"foo.bar.baz">>, [{foo, [{bar, [{baz, wibble}]}]}]).
wibble =:= kvc:path("foo.bar.baz", [{foo, [{bar, [{baz, wibble}]}]}]).

mochijson2 {struct, proplist()} example:

<<"wibble">> =:= kvc:path([<<"foo">>, <<"bar">>, <<"baz">>],
                     {struct,
                      [{<<"foo">>,
                        {struct,
                         [{<<"bar">>,
                           {struct, [{<<"baz">>, <<"wibble">>}]}}]}}]}).

<<"wibble">> =:= kvc:path('foo.bar.baz',
                     {struct,
                      [{<<"foo">>,
                        {struct,
                         [{<<"bar">>,
                         {struct, [{<<"baz">>, <<"wibble">>}]}}]}}]}).

maps example:

<<"wibble">> = kvc:path("foo.bar.baz",
                   #{<<"foo">> => #{<<"bar">> => #{<<"baz">> => <<"wibble">>}}}).

Collection operator example:

2.0 =:= kvc:path([<<"foo">>,<<"bar">>,<<"baz">>,<<"@avg">>],
                 {struct,
                  [{<<"foo">>,
                   {struct,
                    [{<<"bar">>,
                     {struct, [{<<"baz">>, [1, 2, 3]}]}}]}}]}).

2.0 =:= kvc:path('foo.bar.baz.@avg',
                 {struct,
                  [{<<"foo">>,
                   {struct,
                    [{<<"bar">>,
                     {struct, [{<<"baz">>, [1, 2, 3]}]}}]}}]}).

to_proplist normalization:

[{<<"foo">>, [{<<"bar">>, <<"baz">>}]}] =:=
    kvc:to_proplist({struct,
                     [{<<"foo">>,
                       {struct,
                        [{<<"bar">>, <<"baz">>}]}}]}).

More Repositories

1

couchperuser

couchperuser is a CouchDB plugin daemon that creates per-user databases
Erlang
85
star
2

haskell-for-erlangers-2014

Intro to Haskell for Erlangers @ Erlang Factory SF 2014
Haskell
25
star
3

pyutf8

Python extension for dealing with validation and cleanup of UTF-8 strings
Python
25
star
4

strip_pkg_signature

Strips signature from Apple pkg files
Python
18
star
5

adsense_scraper

Scrapes Google AdSense earnings data with Python using Twill
Python
11
star
6

rndchoice_efl_2012

Random Choice - Erlang Factory Lite 2012 (Moscow, Russia)
JavaScript
8
star
7

python-haskell-ep2014

"What Python can learn from Haskell" EuroPython 2014
CSS
8
star
8

erl_testing_2011

Practical Erlang Testing (Erlang Factory London 2011)
JavaScript
6
star
9

pyfastbit

pyfastbit is a Python interface to the FastBit C++ library
Python
5
star
10

emacs.d

My ${HOME}/.emacs.d nest
Emacs Lisp
5
star
11

markov

Erlang
5
star
12

erlang_deploy_ecug_2010

Deploying Erlang Services at Mochi (ECUG 2010 talk)
JavaScript
4
star
13

beginning-haskell-bayhac-2014

Intro to Haskell tutorial for BayHac 2014
Haskell
4
star
14

intro-to-erlang-2013

Intro to Erlang (Sonoma State 2013 talk)
CSS
4
star
15

ad_serving_in_erlang_ef_2009

Ad Serving in Erlang (Erlang Factory 2009)
JavaScript
4
star
16

why-haskell-2013

"Why Haskell?" presentation
Haskell
4
star
17

statebox_qconsf_2011

Eventually Consistent HTTP with Statebox and Riak (QCon SF 2011)
JavaScript
4
star
18

ad_serving_in_erlang_euc_2008

Ad Serving in Erlang (EUC 2008)
JavaScript
3
star
19

ad_serving_in_erlang_cufp_2008

Ad Serving in Erlang (CUFP 2008)
JavaScript
3
star
20

exploring_erlang_c4_2007

Exploring Erlang (C4[1] 2007)
Erlang
3
star
21

fp-htn-2015

"Functional Programming in Industry" - High Tech Norway 2015
HTML
3
star
22

unbsdiff

Fork of bsdiff 4.3 that produces uncompressed patch files
C
3
star
23

python-haskell-dt2014

"What Python can learn from Haskell", Droptalk 2014 SF
CSS
3
star
24

spherl

Sphero Erlang SDK
Erlang
2
star
25

lingtout

Exporter for lingt.com lists
Python
2
star
26

mochikit_ajax_experience_2006

Intro to MochiKit (The Ajax Experience 2006)
JavaScript
2
star
27

pyobjc_pycon_2005

PyObjC Intro / PyObjC Hacking (PyCon 2005)
Python
2
star
28

offtrac

Offtrac is a distributed issue tracker that coordinates with Trac (proof-of-concept)
Python
2
star
29

drop_acid_osbridge_2009

Drop ACID and think about data (OSBridge 2009)
JavaScript
2
star
30

analysis_pycon_2010

Analysis: The Other Kind of Testing (PyCon 2010)
JavaScript
2
star
31

bob.pythonmac.org

bob.pythonmac.org as a blogofile blog
Python
1
star
32

mochi-air-example

Example of a SWF based Air app in the non-application sandbox that can use MochiAPI
ActionScript
1
star
33

mochi-loadertest

Loader to test how your SWF will behave with Mochi Live Updates
ActionScript
1
star
34

missionbit-renio-2014

Slides for Mission Bit lightning talk @ Renaissance 2014
CSS
1
star
35

macpython_pycon_2004

60 Minutes of MacPython (PyCon 2004)
Python
1
star
36

platformer-phaser

Port of the MelonJS platformer tutorial to phaser
JavaScript
1
star
37

hpydatabook

Scratch repo
Haskell
1
star
38

sicp-haskell

sicp-haskell
Haskell
1
star
39

drop_acid_pycon_2009

Drop ACID and think about data (PyCon 2009)
JavaScript
1
star
40

lexical-esm-sveltekit-vanilla-js

TypeScript
1
star