Closed rikkit closed 10 years ago
Except is supposed to take an array (AFAIK thats standard LINQ). I've fixed the readme to reflect this. I think what you are looking for is either Select or a filter of some sort. Can you show me what you're trying to do with the data in JS?
I'd like it to work as in C# - i.e. return a list which is all the items in list 1 except those also in list 2, determined by a given comparison. The comparison is the bit I'm missing (I'm checking two lists of equivalent but not the same objects).
I think this would be the coffeescript? I don't know how to set up the testing environment to try it out though.
Except: (arr, fn) -> @Where (item) -> !(fn(item) in arr.Select(fn))
You don't have to write it in coffee-script, I do javascript too...
So you make an array and wrap it in a LINQ object (lets say li). You want to get all items in li that are not in another LINQ object (lets say li2). Right?
var li = new LINQ([1,2,3]);
var li2 = new LINQ([3,4,5]);
var exclusive = li.Except(li2.ToArray()).toArray();
console.log(exclusive); // [1, 2]
If you are comparing objects by field you can do something like
var li = new LINQ([{name:"Todd"}, {name:"Rick"}]);
var li2 = new LINQ([{name:"Rick"}, {name: "John"}]);
var getField = function(i){
return i.name;
};
var exclusive = li.Select(getField)
.Except(li2.Select(getField).toArray())
.toArray();
console.log(exclusive); // ["Todd"]
Seeing as the repo is in coffeescript I thought I'd try and "speak the language" :)
That would work... but I would like to maintain the list of objects. With Select().Except() I would have to maintain the original list and search with the results? Like I say in C# Linq this is a bit simpler to use -
// c#
public class Q {
public string Name {get;set;}
public Q(string name) {
Name = name;
}
}
public class QComparer : IEqualityComparer<Q>
{
public bool Equals(Q x, Q y) {
return x.Name == y.Name;
}
public int GetHashCode(Q obj) {
return obj.GetHashCode();
}
}
Usage:
// c#
var l1 = new List<Q>{ new Q("Todd"), new Q("Rick")};
var l2 = new List<Q>{ new Q("Rick"), new Q("John")};
var except = l1.Except(l2, new QComparer()); // { Q{ Name = "Todd"} }
Correct me if I'm wrong but I think this JS is simpler? Instead of passing an"EqualityComparer" object, we can pass a function:
// js
var li = new LINQ([{name:"Todd"}, {name:"Rick"}]);
var li2 = new LINQ([{name:"Rick"}, {name: "John"}]);
var getField = function(i){
return i.name;
};
var exclusive = li.Except(li2, getField).toArray();
console.log(exclusive); // [{name: "Todd}]
If you can help me set up the build environment (I have node.js but haven't managed to get coffeescript compiling and mocha/ jasmine working), I can turn this into a pull request?
Ah I see what you mean. I left out IEqualityComparer for now and I was going to add it later and replace it with functions like you said. There are a few places this needs to go. I will work on this when I get time.
As for dev env: Fork it, git clone your url, npm install in the older, then npm test
identity = (item) -> (item)
Except: (arr, fn = identity) -> @Where (item) -> !(fn(item) in (fn(item) for item in arr))
How's that? Is fn = identity the best way to set a default in CS?
No that isn't right
Do you mean code-style or logically?
The identity variable needs to be named better and it shouldn't be a private variable of the class just put it at the top of the file. The ALINQ implementation needs to be on par with the LINQ one so if you add this to LINQ it needs to be added to ALINQ as well (+ tests)
There are multiple places where the IEqualityComparer needs to be added and it would be better to have it all in one commit
Readme lists it as
but the coffeescript is just
... which makes the function pretty useless. Anyone able to change this? (I'm using the npm in my first node project... and I don't know where to start with coffeescript :( )