Code Monkey home page Code Monkey logo

Comments (8)

swannodette avatar swannodette commented on August 13, 2024

It is possible, in fact Clojure/ClojureScript don't even bother with zip as this behavior is provided by map. However in order for this to work transduce would need to be changed to support multiple collections.

from transducers-js.

RGBboy avatar RGBboy commented on August 13, 2024

I'm intrigued that Clojure/ClojureScript provide this via map. Could you elaborate how this is achieved?

from transducers-js.

swannodette avatar swannodette commented on August 13, 2024

In Clojure/ClojureScript map has a fourth variadic arity, this arity is leveraged by MultiStepper coupled with LazyTransformer. See the Clojure/ClojureScript source for details.

I'll ask around to see if adding zip like functionality to map to this library is desirable.

from transducers-js.

RGBboy avatar RGBboy commented on August 13, 2024

OK great, thanks for looking into this.

from transducers-js.

hura avatar hura commented on August 13, 2024

+1

from transducers-js.

nmn avatar nmn commented on August 13, 2024

This can be done easily with reduce:

[['a', 'b', 'c'][1, 2, 3]].reduce(function(result, item){
   return item.map(function(elem, index){
     return [].concat(result[index]).concat(elem)
   }
}, [])

I wasn't quite sure how to write that with transducers right now

from transducers-js.

shaunc avatar shaunc commented on August 13, 2024

Can be done like this...

import tr from 'transducers-js';

function zip() {
  return xf => Zip(xf);
}
const sub = Symbol('sub');
function Zip(xf) {
  return {
    ['@@transducer/init']() {
      const result = { [sub]: [] };
      // if init is not implemented in wrapped, ignore
      try {
        result.wrapped = xf['@@transducer/init']();
      }
      catch(err) { }
      return result;
    },
    ['@@transducer/result'](result) {
      if(result[sub] == null || result[sub].length === 0) {
        return result.wrapped || result;  
      }
      const wrappedResult = result[sub][0].reduce((acc, input, i)=>
        xf['@@transducer/step'](acc, result[sub].map((a)=>a[i]))
      , result.wrapped);
      return xf['@@transducer/result'](wrappedResult);
    },
    ['@@transducer/step'](result, input) {
      if(result[sub] == null) {
        // "into" - init not called
        const acc = this['@@transducer/init']();
        // pass the evil on to the wrapped accumulator
        acc.wrapped = result;
        result = acc;
      }
      result[sub].push(input);
      return result;
    }
  };
}
console.log(tr.into([], zip(), [[1,2,3], [4,5,6]]));
// output: [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ]

Grumble

IMHO, the protocol should always call '@@transducer/init' -- every transformer should be able to set up its own accumulator. As the point is to abstract away from the underlying object collections, there is no reason my "step" function should be passed the "empty" object from into -- rather I should get my own accumulator on each step -- and pass the next transformer in the chain its own accumulator (which I could have wrapped in mine and stored in "init" -- but more conveniently, perhaps, would be passed in for me).

Perhaps I am missing something? Instead of putting state into the accumulator, I could store it in the transformer itself (or also in the closure that creates the transformer object). But why chain the accumulators at all if they aren't meant to store state? The question would be -- what would be expected of the code:

const zip0 = zip();
console.log(tr.into([], zip0, [[1,2,3], [4,5,6]]));
console.log(tr.into([], zip0, [[1,2,3], [4,5,6]]));

Presumably this is wrong (?) -- into() expects something stateless and then (should) set up?

from transducers-js.

xgbuils avatar xgbuils commented on August 13, 2024

Hi @shaunc

Your zip transducer doesn't work well:

const input = [[1,2,3], [4,5,6]]
const transducer = tr.comp(
  zip(),
  tr.take(2)
)
const output = tr.into([], transducer, input)
console.log(output); /* { 
  '@@transducer/reduced': true,
  '@@transducer/value': [ [ 1, 4 ], [ 2, 5 ] ]
} */

Cheers!

from transducers-js.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.