Is it ok to use conditional splice?
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
add a comment |
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
why do you consider this to be the correct output? What would you expect for an input ofmy @x = ( 1, 5, 9,1,1);
– clamp
Jan 2 at 18:29
Sorry for misprint, of course1 9
is not correct output. Fixed the question.
– Paul Serikov
Jan 3 at 7:15
add a comment |
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
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
perl
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 ofmy @x = ( 1, 5, 9,1,1);
– clamp
Jan 2 at 18:29
Sorry for misprint, of course1 9
is not correct output. Fixed the question.
– Paul Serikov
Jan 3 at 7:15
add a comment |
why do you consider this to be the correct output? What would you expect for an input ofmy @x = ( 1, 5, 9,1,1);
– clamp
Jan 2 at 18:29
Sorry for misprint, of course1 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
add a comment |
1 Answer
1
active
oldest
votes
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.
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, thegrep
route is still the simplest by far.
– ikegami
Jan 3 at 3:41
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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, thegrep
route is still the simplest by far.
– ikegami
Jan 3 at 3:41
add a comment |
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.
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, thegrep
route is still the simplest by far.
– ikegami
Jan 3 at 3:41
add a comment |
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.
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.
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, thegrep
route is still the simplest by far.
– ikegami
Jan 3 at 3:41
add a comment |
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, thegrep
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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