Is it ok to use conditional splice?












2















Let's consider simple Perl code:



my @x = ( 1, 5, 9);

for my $i ( 0 .. $#x ) {
splice( @x, $i, 1 ) if ( $x[$i] >= 5 );
}

print "@x";


Output is not correct, 1 9 but there must be 1



If we run code with -w flag it prints warning



Use of uninitialized value within @x in numeric ge (>=) at splice.pl line 5.


So, it's not good practise to use conditional splice and better to push result in new variable?










share|improve this question

























  • why do you consider this to be the correct output? What would you expect for an input of my @x = ( 1, 5, 9,1,1);

    – clamp
    Jan 2 at 18:29













  • Sorry for misprint, of course 1 9 is not correct output. Fixed the question.

    – Paul Serikov
    Jan 3 at 7:15
















2















Let's consider simple Perl code:



my @x = ( 1, 5, 9);

for my $i ( 0 .. $#x ) {
splice( @x, $i, 1 ) if ( $x[$i] >= 5 );
}

print "@x";


Output is not correct, 1 9 but there must be 1



If we run code with -w flag it prints warning



Use of uninitialized value within @x in numeric ge (>=) at splice.pl line 5.


So, it's not good practise to use conditional splice and better to push result in new variable?










share|improve this question

























  • why do you consider this to be the correct output? What would you expect for an input of my @x = ( 1, 5, 9,1,1);

    – clamp
    Jan 2 at 18:29













  • Sorry for misprint, of course 1 9 is not correct output. Fixed the question.

    – Paul Serikov
    Jan 3 at 7:15














2












2








2


1






Let's consider simple Perl code:



my @x = ( 1, 5, 9);

for my $i ( 0 .. $#x ) {
splice( @x, $i, 1 ) if ( $x[$i] >= 5 );
}

print "@x";


Output is not correct, 1 9 but there must be 1



If we run code with -w flag it prints warning



Use of uninitialized value within @x in numeric ge (>=) at splice.pl line 5.


So, it's not good practise to use conditional splice and better to push result in new variable?










share|improve this question
















Let's consider simple Perl code:



my @x = ( 1, 5, 9);

for my $i ( 0 .. $#x ) {
splice( @x, $i, 1 ) if ( $x[$i] >= 5 );
}

print "@x";


Output is not correct, 1 9 but there must be 1



If we run code with -w flag it prints warning



Use of uninitialized value within @x in numeric ge (>=) at splice.pl line 5.


So, it's not good practise to use conditional splice and better to push result in new variable?







perl






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 3 at 7:14







Paul Serikov

















asked Jan 2 at 18:21









Paul SerikovPaul Serikov

532219




532219













  • why do you consider this to be the correct output? What would you expect for an input of my @x = ( 1, 5, 9,1,1);

    – clamp
    Jan 2 at 18:29













  • Sorry for misprint, of course 1 9 is not correct output. Fixed the question.

    – Paul Serikov
    Jan 3 at 7:15



















  • why do you consider this to be the correct output? What would you expect for an input of my @x = ( 1, 5, 9,1,1);

    – clamp
    Jan 2 at 18:29













  • Sorry for misprint, of course 1 9 is not correct output. Fixed the question.

    – Paul Serikov
    Jan 3 at 7:15

















why do you consider this to be the correct output? What would you expect for an input of my @x = ( 1, 5, 9,1,1);

– clamp
Jan 2 at 18:29







why do you consider this to be the correct output? What would you expect for an input of my @x = ( 1, 5, 9,1,1);

– clamp
Jan 2 at 18:29















Sorry for misprint, of course 1 9 is not correct output. Fixed the question.

– Paul Serikov
Jan 3 at 7:15





Sorry for misprint, of course 1 9 is not correct output. Fixed the question.

– Paul Serikov
Jan 3 at 7:15












1 Answer
1






active

oldest

votes


















12














The problem isn't your use of conditional splice per se, it's your loop. The most obvious problem, and the one that causes your warning, is that you're running off of the end of the array. for my $i ( 0 .. $#x ) sets the iteration endpoint to $#x before the loop starts, but after you splice one or more elements out, the last index of the array will be smaller. You could fix that using a C-style for loop, instead of the range-style loop, but I don't recommend it — keep reading.



The next problem is that after you splice an element out of the array, you continue the loop with $i one higher... but because you spliced an element out of the array, the next element that you haven't seen yet is in $x[$i], not $x[$i+1]. You say "Output is correct, 1 9", but shouldn't 9 have been removed, since it's more than 5? You could fix this using redo after splice to go through the loop again without incrementing $i, but I don't recommend that either.



So it is possible to fix your loop which uses splice in place so that it will work correctly, but the result would be pretty complicated. Unless there's a compelling reason to do it differently, I would recommend using simply



@x = grep { $_ < 5 } @x;


There's no problem with assigning the result to the same array as the source, and there is no loop management or other housekeeping for you to do.






share|improve this answer
























  • Re "but the result would be pretty complicated", A common way to simplify this is to iterate over the indexes backwards (from highest to lowest). Of course, the grep route is still the simplest by far.

    – ikegami
    Jan 3 at 3:41











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54011282%2fis-it-ok-to-use-conditional-splice%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









12














The problem isn't your use of conditional splice per se, it's your loop. The most obvious problem, and the one that causes your warning, is that you're running off of the end of the array. for my $i ( 0 .. $#x ) sets the iteration endpoint to $#x before the loop starts, but after you splice one or more elements out, the last index of the array will be smaller. You could fix that using a C-style for loop, instead of the range-style loop, but I don't recommend it — keep reading.



The next problem is that after you splice an element out of the array, you continue the loop with $i one higher... but because you spliced an element out of the array, the next element that you haven't seen yet is in $x[$i], not $x[$i+1]. You say "Output is correct, 1 9", but shouldn't 9 have been removed, since it's more than 5? You could fix this using redo after splice to go through the loop again without incrementing $i, but I don't recommend that either.



So it is possible to fix your loop which uses splice in place so that it will work correctly, but the result would be pretty complicated. Unless there's a compelling reason to do it differently, I would recommend using simply



@x = grep { $_ < 5 } @x;


There's no problem with assigning the result to the same array as the source, and there is no loop management or other housekeeping for you to do.






share|improve this answer
























  • Re "but the result would be pretty complicated", A common way to simplify this is to iterate over the indexes backwards (from highest to lowest). Of course, the grep route is still the simplest by far.

    – ikegami
    Jan 3 at 3:41
















12














The problem isn't your use of conditional splice per se, it's your loop. The most obvious problem, and the one that causes your warning, is that you're running off of the end of the array. for my $i ( 0 .. $#x ) sets the iteration endpoint to $#x before the loop starts, but after you splice one or more elements out, the last index of the array will be smaller. You could fix that using a C-style for loop, instead of the range-style loop, but I don't recommend it — keep reading.



The next problem is that after you splice an element out of the array, you continue the loop with $i one higher... but because you spliced an element out of the array, the next element that you haven't seen yet is in $x[$i], not $x[$i+1]. You say "Output is correct, 1 9", but shouldn't 9 have been removed, since it's more than 5? You could fix this using redo after splice to go through the loop again without incrementing $i, but I don't recommend that either.



So it is possible to fix your loop which uses splice in place so that it will work correctly, but the result would be pretty complicated. Unless there's a compelling reason to do it differently, I would recommend using simply



@x = grep { $_ < 5 } @x;


There's no problem with assigning the result to the same array as the source, and there is no loop management or other housekeeping for you to do.






share|improve this answer
























  • Re "but the result would be pretty complicated", A common way to simplify this is to iterate over the indexes backwards (from highest to lowest). Of course, the grep route is still the simplest by far.

    – ikegami
    Jan 3 at 3:41














12












12








12







The problem isn't your use of conditional splice per se, it's your loop. The most obvious problem, and the one that causes your warning, is that you're running off of the end of the array. for my $i ( 0 .. $#x ) sets the iteration endpoint to $#x before the loop starts, but after you splice one or more elements out, the last index of the array will be smaller. You could fix that using a C-style for loop, instead of the range-style loop, but I don't recommend it — keep reading.



The next problem is that after you splice an element out of the array, you continue the loop with $i one higher... but because you spliced an element out of the array, the next element that you haven't seen yet is in $x[$i], not $x[$i+1]. You say "Output is correct, 1 9", but shouldn't 9 have been removed, since it's more than 5? You could fix this using redo after splice to go through the loop again without incrementing $i, but I don't recommend that either.



So it is possible to fix your loop which uses splice in place so that it will work correctly, but the result would be pretty complicated. Unless there's a compelling reason to do it differently, I would recommend using simply



@x = grep { $_ < 5 } @x;


There's no problem with assigning the result to the same array as the source, and there is no loop management or other housekeeping for you to do.






share|improve this answer













The problem isn't your use of conditional splice per se, it's your loop. The most obvious problem, and the one that causes your warning, is that you're running off of the end of the array. for my $i ( 0 .. $#x ) sets the iteration endpoint to $#x before the loop starts, but after you splice one or more elements out, the last index of the array will be smaller. You could fix that using a C-style for loop, instead of the range-style loop, but I don't recommend it — keep reading.



The next problem is that after you splice an element out of the array, you continue the loop with $i one higher... but because you spliced an element out of the array, the next element that you haven't seen yet is in $x[$i], not $x[$i+1]. You say "Output is correct, 1 9", but shouldn't 9 have been removed, since it's more than 5? You could fix this using redo after splice to go through the loop again without incrementing $i, but I don't recommend that either.



So it is possible to fix your loop which uses splice in place so that it will work correctly, but the result would be pretty complicated. Unless there's a compelling reason to do it differently, I would recommend using simply



@x = grep { $_ < 5 } @x;


There's no problem with assigning the result to the same array as the source, and there is no loop management or other housekeeping for you to do.







share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 2 at 18:30









hobbshobbs

144k14150236




144k14150236













  • Re "but the result would be pretty complicated", A common way to simplify this is to iterate over the indexes backwards (from highest to lowest). Of course, the grep route is still the simplest by far.

    – ikegami
    Jan 3 at 3:41



















  • Re "but the result would be pretty complicated", A common way to simplify this is to iterate over the indexes backwards (from highest to lowest). Of course, the grep route is still the simplest by far.

    – ikegami
    Jan 3 at 3:41

















Re "but the result would be pretty complicated", A common way to simplify this is to iterate over the indexes backwards (from highest to lowest). Of course, the grep route is still the simplest by far.

– ikegami
Jan 3 at 3:41





Re "but the result would be pretty complicated", A common way to simplify this is to iterate over the indexes backwards (from highest to lowest). Of course, the grep route is still the simplest by far.

– ikegami
Jan 3 at 3:41




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54011282%2fis-it-ok-to-use-conditional-splice%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Angular Downloading a file using contenturl with Basic Authentication

Olmecas

Can't read property showImagePicker of undefined in react native iOS