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

Making EnumerableImpl [[call]]able #81

Closed
gerneio opened this issue Jan 22, 2019 · 1 comment
Closed

Making EnumerableImpl [[call]]able #81

gerneio opened this issue Jan 22, 2019 · 1 comment

Comments

@gerneio
Copy link
Contributor

gerneio commented Jan 22, 2019

This is hardly even a feature request, more of sharing one of my ideas, which I doubt will hold much value for most people. However I wanted to mention it as it's useful in my use case.

Brief background:

I am using this library in conjunction with my forked lib jsonQuery which is the XPath of JSON. My forked lib has implemented various enhancements so that it is easier to query a deeply heirichal object with as few lines AND characters of code as possible.

I.E.

var data = {
  grouped_people: {
    'friends': [
      {name: 'Steve', country: 'N Z', age: 1},
      {name: 'Jane', country: 'US', age: 2},
      {name: 'Mike', country: 'AU', age: 3},
      {name: 'Mary', country: 'N Z', age: 4},
    ],
    'enemies': [
      {name: 'Evil Steve', country: 'AU', age: 5},
      {name: 'Betty', country: 'N Z', age: 6}
    ]
  }
};
...
// get ALL nested age elements
data["$..age"]; // [ 1, 2, 3, 4, 5, 6 ]

The queries can get much more complex, but still be able to be "one-liners", which is ideal for my situation, the least amount of characters the better.

Now back to my point here. As I mentioned, I'm heavily incorporating LINQ into this, partly cause I'm familiar with C# LINQ, but also because of it's aggregate properties. For the most part the lib is easily extensible. For example, I've added an 'SumA' and 'AverageA' methods that don't error out on non-numeric values, and/or an exclusion of blank values. Along with prototyping EnumerableImpl directly to Array, which works surprisingly well.

var _EnumerableImpl = Enumerable.From([]).constructor;

Object.setPrototypeOf(Array.prototype, _EnumerableImpl.prototype);

_EnumerableImpl.prototype.FuncA = function(a, f) { return this.Select(a || (e => e))[f](e => isNaN(e) ? null : parseInt(e, 10)) } ;

_EnumerableImpl.prototype.AverageA = function(a) { return this.FuncA(a, "Average") };
_EnumerableImpl.prototype.SumA = function(a) { return this.FuncA(a, "Sum") };

data["$..age.SumA()"]; //21

One other thing that I'm thinking would be nice to add to this LINQ lib, is quick function call and return of the 'ToArray()' function. Example:

// The last set of parenthesis is an implicit call to 'ToArray()'
data.grouped_people.friends.Select(e => e.name)(); // [ "Steve", "Jane", "Mike", "Mary" ]

In some of my more complex query strings, I can see this being useful.

This is how I have implemented it and got it to work:

class EnumerableImpl extends Function {
    constructor(target, factory, arg) {
		super();

		... existing function body ...
		
		return new Proxy(this, { apply : () => this.ToArray() });
    } ...

So really not much code to add, and of course this is the browserfied code I'm working with. However I'm sure there are many reasons why not to do that. Ideally, i'd rather just prototype the thing and add this functionality, BUT I haven't figured out how to do that yet.

Just sharing!

HB

@ENikS
Copy link
Owner

ENikS commented Jan 22, 2019

There are arguments for and against your approach.
I would be interested to see what you could come up with. Keep me posted 👍

@ENikS ENikS closed this as completed Jul 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants