1

How to delete the elements of array from index 4 to 10. I am doing like this

#!usr/bin/perl
@array=1..10;
@array[0..3]=@array[5..8];
@array[4..10]=();
$str=(join ",",@array);
print "$str\n";

and getting output as

6,7,8,9,,,,,,,

How to remove extra ","?

3 Answers 3

7

You're doing a bit more than trying to delete elements of the array in that code...

Anyways, you want splice to remove a contiguous range of array elements:

splice @array, 4, 6;
Sign up to request clarification or add additional context in comments.

Comments

3

I'm assuming this is some kind of homework question, because if it's not you're doing some REALLY strange things with this code.

But let's take the problem at hand - the easiest way to filter an array is with grep

my @no_empty = grep { defined  } @array;
print join ( ",", @no_empty ) 

In this we use grep to filter out any undef array elements. The element is returned if the expression in the braces evaluates as true - $_ is set to the current element, and used in any tests that implicitly work on $_. defined does, as does regular expression matches.

However if you genuinely just want to truncate the array to an arbitrary number, you can just do:

@array = @array[0..4]

Comments

3

You start with this array:

 my @array = 1..10;

Now you have an array of 10 elements.

1 2 3 4 5 6 7 8 9 10

In your next step, you perform an array slice then assign that to another array slice:

@array[0..3] = @array[5..8];

This leaves alone the elements from 5 to 8, but does a list assignment of their values to the elements from 0 to 3, so you end up with some duplicated elements:

6 7 8 9 5 6 7 8 9 10

Now you want to get rid of everything after index 4. You try that with another list assignment:

@array[4..10] = ();

However, that just assigns the list on the right to the list on the right. As with any list assignment, the left hand elements get their corresponding elements from the right hand list. If the right hand list doesn't have enough elements, Perl uses undef for the rest of the right hand elements. That's why you still have 10 elements in @array:

6 7 8 9 undef undef undef undef undef undef undef

If you want 4 to be the last index, you can assign to the last index of the array. Whatever number you assign becomes the last index, either shortening or extending the array. Since you wanted to get rid of elements 4 and beyond, you can set the last index to 3 (the index right before the one you want to remove):

 $#array = 3;

Now you've truncated the array to four elements:

6 7 8 9

You can also do this with splice, which replaces part of an array:

splice @array, $start_index, $length, @replacement;

You might use the starting index to figure out the length since you want to go all the way to the end. Then, replace that portion of the array with the empty list, which effectively makes the array shorter:

my $start = 4;
splice @array, $start, @array - $start, ();

Leaving off the replacement list is the same as the empty list:

splice @array, $start, @array - $start;

This is much more handy when you want to remove parts in the middle. This removes three elements starting at index 4 (so there will be stuff left over at the end):

splice @array, 4, 3;

Now your array has elements that were at the beginning and end of your array:

6,7,8,9,8,9,10

Without shortening the array

There's another sort of problem. You don't want to change the array, but you don't want to deal with empty fields. You can use a grep to select only the defined elements:

say join ',', grep { defined } @array;

If you have undefined elements in the middle of the array, this might be a problem if you expect columns to line up properly. Removing a column in the middle shifts the other columns. You may not care about that though.

Similarly, you might turn the undefined values into something that makes sense for the problem. A map can inspect the value and decide to pass it through or transform it. In this example, undef values turn into 0:

say join ',', map { defined ? $_ : 0  } @array;

6,7,8,9,0,0,0,0,0,0,0

Or "NULL":

say join ',', map { defined ? $_ : 'NULL'  } @array;

6,7,8,9,NULL,NULL,NULL,NULL,NULL,NULL,NULL

Or even just undef as a string:

say join ',', map { defined ? $_ : 'undef'  } @array;

6,7,8,9,undef,undef,undef,undef,undef,undef,undef

Sometimes those are handy to see what's going on.

And map can act like grep to filter an array. Use the empty list to pass on no elements from the map:

say join ',', map { defined ? $_ : ()  } @array;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.