Search code examples
javascriptjsonunderscore.jsgenerator

Make Underscorejs functions functioning on generators


I have dozens of functions acting on arrays. See here for the sake of illustration.

As you can see I am using Underscorejs for most operations.

However I want to write a transformation on my main iteratee which is a list of JSON objects like the following:

var listings = [{ title: 'title1', d: 0, desc: 'hello world', pass: 'qub7s1ya', tags: ["tag1", "tag2"] }]

As I want to really optimize performance, I want to write a transformer on desc values. I will be using lzutf8 for this; So that I store in disk and in memory only compressed values. On each Underscorejs operation I would like to act on the decompressed value of key desc.

Apparently, Underscore operations do not act on generators directly, so my question is how to achieve this ?

Edit1: I believe all operations of Underscorejs are sequential, so why not support generators ? or am I missing something ?

Edit2: The operations are those acting on "key-value" in a JSON object or an array like

_#filter, _#findWhere, _#where, _#reject, _#pick


Solution

  • At first, I thought of generators to be able to change each item at runtime to be able to have an plain text from a compressed one. Similarly (I think at least for now), it can be achieved by attaching a calculated property to a JSON object, this is possible in JavaScript. Something like:

    var item = {
        desc: "compressed text", 
    }
    
    Object.defineProperty(item, 'desc_', {
      get: function() { return decompress(this.desc) }
    });
    console.log(item.desc_)
    console.log(JSON.parse(JSON.stringify(item)))
    

    Then I don't worry about other functions acting on desc only by replacing desc by desc_.

    Also apparently adding a function using Object.defineProperty does not affect JSON.stringify in contrary to redefining another JSON with a getter like:

    var item = {
        desc: "hello world", 
        get desc_(){ return (this.desc.toUpperCase()); },
        toJSON() {
          return {
            desc: this.desc 
          }
      }
    }
    

    where toJSON must be defined otherwise desc_ will be calculated and persisted (for some reason!).

    Back to Underscore.js question. All needed operations seem to work with the new calculated property.

    Example of where:

    listings = [{ title: 'title1', d: 0, desc: 'oipfjezojifze', pass: 'qub7s1ya', tags: ["tag1", "tag2"] }]
    listings.forEach(item => {
        Object.defineProperty(item, 'desc_', {
            get: function () { return (this.desc.toUpperCase()) }
        });
    });
    var results = _.where(listings, { desc_: "oipfjezojifze".toUpperCase() })
    // it also returns the object intact
    console.log(results[0].desc_)
    // and other methods _#filter, _#findWhere, _#where, _#reject, _#pick do as well