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

feat(List): add move function #2694

Merged
merged 6 commits into from
Nov 21, 2018
Merged

Conversation

MadDeveloper
Copy link
Contributor

As discussed here: #2692

Copy link
Member

@CrossEye CrossEye left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the PR. There are several suggestions here, and a question for the @ramda/core team: As well as the obvious question of whether you think this function is worth including, I also would like to know if you think it should apply to any indexable type.

.concat(result.slice(0, to))
.concat(item)
.concat(result.slice(to, list.length));
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although I'm the one who suggested that this be done on the native methods, I'm having some second thoughts. Would this do well working on all indexable types? Strings would be an obvious fit, but should it also work on NodeList, on ArgumentList, and so on?

What do you think, @ramda/core?

source/move.js Outdated Show resolved Hide resolved
test/move.js Outdated Show resolved Hide resolved
test/move.js Outdated
eq(R.move(-1, 0, [1,2,3]), [3,1,2]);
});

it('should move the element at the end when the destination index is outside liste bounds', function() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But is this the correct behavior? Why do we distinguish how it behaves with the source index and the destination one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of the flexibility of move() and more precisely splice and slice, we are able to make a list rotation, but it has some unexpected behaviour, like this one you pointed out. How do you think prevent this behaviour without breaking the rotation one? Should we prevent only the positive outbounds? Because the negative outbounds can be a desired behaviour.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not quite sure. Perhaps we want to allow negative outbounds only down to the first element. I really don't like this asymmetry:

move(-50, 2, ['a', 'b', 'c', 'd', 'e', 'f']) //=> ['b', 'c', 'a', 'd', 'e', 'f']
move( 50, 2, ['a', 'b', 'c', 'd', 'e', 'f']) //=> ['a', 'b', 'c', 'd', 'e', 'f']

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe these ones are enough:

move(0, -1, ['a', 'b', 'c']) /// ['b', 'c', 'a']
move(-1, 0, ['a', 'b', 'c']) /// ['c', 'a', 'b']

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That also seems odd to me. If we're going to allow negative indices, these seem reasonable too:

move(-2, 1, ['a', 'b', 'c', 'd', 'e', 'f']) //=> ['a', 'e', 'b', 'c', 'd', 'f']
move(1, -2, ['a', 'b', 'c', 'd', 'e', 'f']) //=> ['a', 'c', 'd', 'e', 'b', 'f']

Generally, if -1 gets special treatment it's as a not-found signal, as in Array.prototype.findIndex

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems better. It looks like a first version I wrote, but that I've lightened in order to remove check verifications as I didn't know if Ramda desired them: Here is the tests that were in the move function:

// all exclusive tests
if (typeof from !== 'number' 
  || typeof to !== 'number'
  || from > length - 1
  || from < 0
  || to > length - 1
  || to < 0
  || from === to
  || length === 0) {
  return result
}

Negative indices were totally excluded.
Rewriting them with positiveFrom and positiveTo can do the job perfectly and make more sense.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to do that update? I'd be inclined to accept this with that change, although I would still like some feedback from @ramda/core .

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated. I didn't add the realIndex function in the internal directory, as I don't know if it should be added in a separate PR. Let me know if you want to see it appears in this PR.

Copy link
Member

@CrossEye CrossEye Nov 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I'm afraid that this code combines two of what I think of contradictory suggestions of mine.

I was suggesting something like this except with

  var positiveFrom = from < 0 ? list.length + from : from;
  var positiveTo = to < 0 ? list.length + to : to;

so that

move(-2,  1, ['a', 'b', 'c', 'd', 'e', 'f']) //=> ['a', 'e', 'b', 'c', 'd', 'f']
move( 1, -2, ['a', 'b', 'c', 'd', 'e', 'f']) //=> ['a', 'c', 'd', 'e', 'b', 'f']
move(-50, 2, ['a', 'b', 'c', 'd', 'e', 'f']) //=> ['a', 'b', 'd', 'd', 'e', 'f']
move( 50, 2, ['a', 'b', 'c', 'd', 'e', 'f']) //=> ['a', 'b', 'c', 'd', 'e', 'f']

The idea is that a negative index only does something up to the length of the list. After that, it becomes a no-op. I think that stopping at the end of the array is far too surprising.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I think there was a misunderstanding... I fixed it and I hope everything is ok now.

test/move.js Outdated Show resolved Hide resolved
test/move.js Outdated Show resolved Hide resolved
@CrossEye CrossEye merged commit 89f4540 into ramda:master Nov 21, 2018
@CrossEye
Copy link
Member

Merged. Thank you for your persistence.

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

Successfully merging this pull request may close these issues.

None yet

3 participants