Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Another solution for Duplex Redux #85

Open
sray opened this issue Oct 13, 2014 · 1 comment
Open

Another solution for Duplex Redux #85

sray opened this issue Oct 13, 2014 · 1 comment

Comments

@sray
Copy link

sray commented Oct 13, 2014

I think for those wondering how to solve the Duplex Redux challenge without using "through", it would be good to add an alternative official solution to compare to.

Here is my solution for the challenge without using "through". I am not sure if the code fulfills latest node and javascript best practices, but it works. It also might be good to point out why solving the challenge with "through" might be preferable to creating a writable stream explicitely on your own.

var spawn = require('child_process').spawn
var Stream = require('stream')
var duplexer = require('duplexer')


module.exports = function (counter) {
  var inwrite = new Stream.Writable({objectMode: true})

  var countryCounts = {}

  inwrite._write = function (chunk, enc, next) {    
    //what to do with the chunk
    if (countryCounts[chunk.country]) {
      countryCounts[chunk.country] = countryCounts[chunk.country] + 1
    } else {
      countryCounts[chunk.country] = 1
    }

    next()
  }

  inwrite.on('finish', function() {
    //in the end: set countryCounts in readable stream
    counter.setCounts(countryCounts)
  })

  return duplexer(inwrite, counter)
}
@ghost
Copy link

ghost commented Apr 21, 2015

Thanks @Saheba, I am sure some people will find this useful as they make their way through Node.

You don't need var spawn = require('child_process').spawn.

Also, unwary users don't get caught off guard by { objectMode: true }, this bit (well not just one bit) is essential.

Basically:

Streams that are in object mode can emit generic JavaScript values other than Buffers and Strings.

Here is a slightly simpler version using your own code:

var Stream = require('stream')
var duplexer = require('duplexer')

module.exports = function (counter) {
  var countryCounts = {}

  var inwrite = new Stream.Writable({objectMode: true})

  inwrite._write = function (chunk, enc, next) {
    if (countryCounts[chunk.country]) {
      countryCounts[chunk.country] = countryCounts[chunk.country] + 1
    } else {
      countryCounts[chunk.country] = 1
    }
    next()
  }

  inwrite.end = function(d) {
    counter.setCounts(countryCounts)
  }

  return duplexer(inwrite, counter)
}

Here is an neat solution using kthulhu (through2 like but simpler)

var duplexer = require('duplexer')
var $ = require('kthulhu')

module.exports = function (counter) {
  var counts = {}

  return duplexer($(
    function (row) {
      counts[row.country] = (counts[row.country] || 0) + 1;
    },
    function () {
      counter.setCounts(counts)
    }), counter)
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants