Loading collection data...
Collections are a way for you to organize kata so that you can create your own training routines. Every collection you create is public and automatically sharable with other warriors. After you have added a few kata to a collection you and others can train on the kata contained within the collection.
Get started now by creating a new collection.
Ah okay. Thanks.
That means solvers need to give more ratings and rankings.
I just noticed that the Beta Status for this kata still says 'Testing and feedback needed'. I thought I had taken care of the testing on this, but please do let me know if there is something else required. Thanks.
Got it. Thanks again for all your help.
Yes, minding that
.slice()
only copies on the first level of its argument, so if you are passing anArray
ofArray
s, you should be passing inarg.map( sub => sub.slice() )
(.map()
returns a newArray
on the first level,.slice()
on the second ). As Unnamed said, there are alternatives for true deep cloning, but this'll work for the job at hand.Wow, thank you for taking the time to write all that. So let me make sure I get this: because arrays are passed by reference in JavaScript, modifications to the array from within the function will of course also change the array from outside of the function. So I should pass in deep copies of the array using the slice function. Is that correct?
Hi again. My background is with Java so I'm pretty familiar with OOP. I was speaking from the point of view of encapsulation. Having said that, the properties in my JavaScript version are public so I suppose I've no cause to question the public variables in your translation!
Thanks for the link on C# naming guidelines. I didn't know they differed from Java in that way.
Hi, the methods being used are on a class because, like Java, C# is a strictly OOP language and everything is done inside a class. Variables being public also allow them to be accessed outside the class itself.
As for the capitalization of properties/methods, they follow C# member naming guidelines which specify that public properties/methods should be PascalCased, which you can see here.
Hiya. I hope this doesn't come across as pedantic, and I'm not that familiar with C#, but should the variable names be public and starting with a capital letter? Or are getters & setters considered to be overkill for this kind of challenge? Thought I'd better check what I was approving first!
Array.prototype.slice
andObject.assign
make shallow copies; for deep copying there arecloneDeep
inlodash
orJSON.parse(JSON.stringify())
as a quick hack.Hi AtomicTanuki, make sure you press the "Approve" button on that page.
Basically, yes.
The expected value being an unchanged array was not actually unchanged. All odd subarrays were being reversed twice, so it looked unchanged. It was an artifact of reusing the argument from the user solution to the reference solution. So that'll go away if you fix the modification vulnerability. ( I had forgotten that
.reverse()
changes its argument in place, and I was not taking into account subarrays could be reused as well as the outer array. I thought I was safe because I returned a new copy of the outer array. )The way to fix that has been explained on countless other first ( and later ) kata, but here goes again ( sigh .. ) :
Give user a copy of any
Object
random input argument, and/or calculate theexpected
value first. Make damn sure the reference solution is not modifying its argument, or give the reference solution its own copy of the original.Short story long(er): when passing arguments, JavaScript passes non-primitive arguments ( i.e., all
Object
s, includingArray
s ) by reference. If you change properties of that argument in your function, the caller sees his variable change as well. Primitive values are safe from this ( either because they are passed by value, or because they are immutable. I'm not sure any more which one is the actual reason, but passing primitiveString
s,Number
s andBoolean
s is safe ).Creating deep copies of
Array
s can be accomplished witha.slice()
, ofObject
s withObject.assign({},o)
, other objects, custom ones and such, you may need to go through the appropriate constructor again.Whenever you are passing arguments other than primitive values, you should be on your toes to make damn sure your reference solution does not modify its argument(s) and your tests are immune to it being done by the user solution. Your reference solution for this kata does not modify its arguments ( kudos! ); your testing is vulnerable. Implement either of the fixes mentioned above, and you're good to go.
I'm not sure what to do about that. Is it always necessary to have random tests when writing a kata?
See my solution. If I change the input parameter in my solution, the modified argument is used to calculate the expected output.
I had already looked at your testing code. I said it was unclear to me why the random tests were expecting an unmodified array, and it still is.
Hmmm. I'm not quite sure what you mean by 'vulnerable to input modification'.
I have basically randomized the number of 'matches' that are passed into the function.
It's probably considered hacky, but this is the test that I wrote:
for (let i = 0; i < 200; i++) {
let matches = [];
let limit = Math.floor(Math.random() * 20)
for (let j = 0; j < limit; j++) {
matches.push(['C1','C2']);
}
Test.assertDeepEquals(contestantSwapper(matches), contestantSwapperCheck(matches));
}
Loading more items...