-
Notifications
You must be signed in to change notification settings - Fork 217
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
Handle edge case where Arrays and Objects are merged #36
Conversation
Handle edge case where the library attempts to merge an array and an object. ``` merge({foo: {bar: true}}, {foo: ["bar"]}) ``` This fix simply replaces the object with the array that is now at the objects location.
@macdja38 could you add a new failing test for this issue? Or make a comment with the output you would expect from your example code above? |
@TehShrike I expect to get |
That makes sense to me. As an aside, it would probably be better to use |
@TehShrike I thought about that but Array.isArray can fail if the value is null or undefined though I suppose we check that before the code gets to that point. |
|
@TehShrike think you could just double check the test before one of us hits that big green merge button? |
The test looks good to me. Looking at it again, I wonder if we could make the "the target isn't an array" case even simpler - if the target isn't an array and we know we're just going to overwrite it, we don't need to iterate over it at all, we can just make a shallow copy and call it good, something like if (Array.isArray(target)) {
dst = dst.concat(target);
src.forEach(function(e, i) {
if (typeof dst[i] === 'undefined') {
dst[i] = e;
} else if (typeof e === 'object') {
dst[i] = deepmerge(target[i], e);
} else {
if (target.indexOf(e) === -1) {
dst.push(e);
}
}
});
} else {
dst = dst.concat(src)
} buuuut, I'd kind of like to wait to merge this (or even think about changing the implementation to something like what I pasted above) until after #37 is merged, as one of the things that happens in that pull request is refactoring the default array merging behavior out into it's own function. After #37 is merged, I think the implementation could look something like this: if (array) {
return Array.isArray(target) ? arrayMerge(target, source, optionsArgument) : source.slice()
} /* else ... */ |
I had another thought - what if the actual expected behavior was that merging That's not what the current behavior is though, so maybe it doesn't matter much. |
(oh, and feel free to give #37 a review to help along its merging!) |
I think we should probably deploy this as soon as possible attempting the test on a current version of this library causes it to throw an exception.
|
It's an awkward bug, but it's not a regression and it's been around for quite a while. I'm for getting it fixed, but I don't think we should feel rushed. Better to fix it right once than fix it one way now, have more discussions later, and decide to fix it a different way. |
Handle edge case where the library attempts to merge an array and an object.
This fix simply replaces the object with the array that is now at the objects location.