Incorrect Enumerable type when object contains length property
eJuke opened this issue · comments
Hello
I tried to use your library with objects with this structure:
const vehicle = {
weight: 1000,
length: 5,
color: "Blue",
...
}
and wanted to filter some values using .where
method
Enumerable.from(vehicle)
.where(i => excludedFields.indexOf(i.Key) == -1)
.toObject(i => i.Key, i => i.Value);
I expected that .from
function would convert my object to KeyValuePair. Unfortunately this method considered that input is array and didn't convert object to KeyValue
I checked the source code and found this statement on the row 300
// array or array like object
if (typeof obj.length == Types.Number) {
return new ArrayEnumerable(obj);
}
It looks like any object with length property will be converted to ArrayEnumerable independent of another properties.
Is it possible to check for Arrays by another way (something like instanceof call)?
Good find, I don't think we need to keep that logic. I would change it to Array.isArray(obj)
, but need to check potential problems.
I've done some tests and it seems like this change is not a good idea. Using Array.isArray(obj)
(or instanceof
) instead of typeof obj.length == Types.Number
would exclude array-like objects, most notably the arguments
object and return values from DOM functions like document.getElementsByTagName()
that return a list of elements.
You can consider this issue a small limitation of the library, but it's probably better to change the name of your length
property to avoid other problems down the line.
Also a small correction to your code, when converting to object use .toObject(i => i.key, i => i.value);
(without the capitalization)
Is it possible to create method .fromObject
or something like this?
We cannot change name of length
property because we have too many models with this property. So renaming will take too much time to support it across the system.
I think it would be odd to create a separate method for such a narrow use-case.
But you can of course create your own helper method which will transform your object to an array of key-value pairs.
Thank you for your response
I created local module with Enumerable extension (patch adds .fromObject
method) and updated linq module to have type definition for the new method. It's suitable for me