0.6.3 • Published 6 years ago

js-object-interface v0.6.3

Weekly downloads
1
License
MIT
Repository
github
Last release
6 years ago

js-object-interface

Wrap JS Objects to create a functional Array-like interface for iteration and whatnot.

The goal here is to make it easier to iterate over, and interact w/, complex data structures.

engines: node >= 9.x

Installation

npm i --save js-object-interface

Example

const applyInterface = require('js-object-interface');

const obj = {a: 1, b: 2};
var $obj = applyInterface(obj, {customMethods});

$obj.get();
$obj.get('key');
$obj.get('key', 'nestedKey', ...);

$obj.set('value');
$obj.set('key', 'value');
$obj.set('key', 'nestedKey', 'value');

$obj.remove('key');
$obj.remove('key', 'nestedKey');

$obj.forEach(() => {});
$obj.forEach(async () => {});

$obj.map(() => {});
$obj.map(async () => {});

$obj.filter(() => {});
$obj.filter(async () => {});

$obj.find(() => {});
$obj.every(() => {});
$obj.some(() => {});

$obj.keys();
$obj.clone(wrap = false);
$obj.assign({a: 1}, {a: 2}, ...);

API

API differs from the JS functional Array method API, so pay close attention - the devil is in the details.

  • .get()
  • .set()
  • .remove()
  • .forEach()
  • .map()
  • .filter()
  • .every()
  • .some()
  • .find()
  • .keys()
  • .clone()
  • .assign()

.get()

const obj = {a: 1, b: 2, c: {d: 3}};
var $obj = applyInterface(obj);

$obj.get() // returns {a: 1, b: 2, c: {d: 3}};
$obj.get('a') // returns 1
$obj.get('c', 'd') // returns 3

.set()

const obj = {a: 1, b: 2, c: {d: 3}};
var $obj = applyInterface(obj);

$obj.set({e: 1}) // replaces the .src obj w/ {e: 1}. Returns `this`.
$obj.set('a', 2)
$obj.set('c', 'd', 4)
$obj.set('e', 'f', 5) // adds property "e" as an Object w/ an "f" property === 5

.remove()

const obj = {a: 1, b: 2, c: {d: 3}};
var $obj = applyInterface(obj);

$obj.remove() // does nothing
$obj.remove('a') // obj === {b:2, c:{d: 3}}
$obj.remove('c', 'd') // obj === {a: 1, b: 2, c: {}}

.forEach()

const obj = {a: 1, b: 2, c: {d: 3}};
var $obj = applyInterface(obj);

$obj.forEach((value, key, $value) => {
  // value: 1,2, {d: 3}
  // key: 'a', 'b', 'c
  // $value: undefined, undefined, $obj
}); // returns `this`.

// Nested .forEach()
$obj.forEach((value, key, $value) => {
  if ($value !== undefined) { // $value is not undefined when key === 'c'
    $value.forEach((value, key) => {
      // value: 3
      // key: 'd'
    });
  }
});

// Async .forEach()
console.log(1);
await $obj.forEach(async (value, key, $value) => {
  await asyncOperation;
  console.log(2);
});
console.log(3);
// Logs 1, 2, 2, 2, 3

.map()

.map() does not modify the .src Object - it returns a new Object.

"param2" wrapResult=false wraps the result in an interface.

const obj = {a: 1, b: 2, c: {d: 3}};
var $obj = applyInterface(obj);

var result = $obj.map((value, key, $value) => {
  return value;
}); // result === {a: 1, b: 2, c: {d: 3}}.


// Nested .map()
var result = $obj.map((value, key, $value) => {
  if ($value !== undefined) { // $value is not undefined when key === 'c'
    return $value
      .map((value, key) => {
        return value;
      });
  }
  return value;
}) // result === {a: 1, b: 2, c: {d: 3}}

// Async .map()
console.log(1);
var result = await $obj.map(async (value, key, $value) => {
  await asyncOperation;
  console.log(2);
  return value;
});
console.log(3);
// result === {a: 1, b: 2, c: {d: 3}}
// Logs 1, 2, 2, 2, 3

.filter()

.filter() does not modify the .src Object - it returns a new Object.

"param2" wrapResult=false wraps the result in an interface.

If all callbacks return false, null is returned.

const obj = {a: 1, b: 2, c: {d: 3}};
var $obj = applyInterface(obj);

var result = $obj
  .filter((value, key, $value) => {
    return true;
  }); // result === {a: 1, b: 2, c: {d: 3}}

// Async .filter()
console.log(1);
var result = await $obj.filter(async (value, key, $value) => {
  await asyncOperation;
  console.log(2);
  return true;
});
console.log(3);
// result === {a: 1, b: 2, c: {d: 3}}
// Logs 1, 2, 2, 2, 3

.every()

.every() iterates over each Object property and if every callback returns true, true is returned, if not, false is returned.

const obj = {a: 1, b: 2, c: {d: 3}};
var $obj = applyInterface(obj);

var result = $obj.every((value, key, $value) => {
  return true;
}); // result === true.

.some()

.some() iterates over each Object property and if at least one callback returns true, true is returned, if not, false is returned.

const obj = {a: 1, b: 2, c: {d: 3}};
var $obj = applyInterface(obj);

var result = $obj.some((value, key, $value) => {
  return true;
}); // result === true.

.find()

.find() iterates over each Object property and returns the first property where the callback returns a "truthy" value.

If no matches are found, undefined is returned.

const obj = {a: 1, b: 2, c: {d: 3}};
var $obj = applyInterface(obj);

var key = $obj.find((value, key, $value) => {
  return true;
}); // key === 'a'

.keys()

Returns Object.keys() on the .src Object or a nested property.

const obj = {a: 1, b: 2, c: {d: 3}};
var $obj = applyInterface(obj);

$obj.keys(); // ['a', 'b', 'c']
$obj.keys('c'); // ['d']
$obj.keys('c', 'z'); // null

.clone()

Returns a recursive (deep) copy of the .src object.

const obj = {a: 1, b: 2, c: {d: 3}};
var $obj = applyInterface(obj);

var obj1 = $obj.clone();
var obj1 = $obj.clone(wrap = true); // wraps obj1 in an interface.

.assign()

Returns a new Object (deep assign).

const obj = {a: 1, b: 2, c: {d: 3}};
var $obj = applyInterface(obj);

var obj1 = $obj.assign({a: 2}, {a: 9}, ...); // obj1 === {a: 9, b: 2, c: {d: 3}};

// To update the .src Object:
obj.set(obj.assign({a: 2}));
  • View src (./lib/index.js) and tests (./tests/main.test.js) for a more detailed understanding of the API.

Custom methods

You can add custom method(s) to your Object.

var obj1 = {a: 1};
var $obj = applyInterface(obj1, {
  call() {
    return 1;
  },
  apply() {
    return 2;
  },
});
$obj.call() // result === 1
$obj.apply() // result === 2

Performance

Now I wouldn't consider the module to be a performance bottleneck, but I should mention that it is not optimized for high-performance applications. View src.

License

MIT

0.6.3

6 years ago

0.6.2

6 years ago

0.6.1

6 years ago

0.6.0

6 years ago

0.5.0

6 years ago

0.4.1

6 years ago

0.4.0

6 years ago

0.3.0

6 years ago

0.2.1

6 years ago

0.2.0

6 years ago

0.1.0

6 years ago