Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

How do I insert an element into an arbitrary (in range) array index?

( #30939=categorized question: print w/ replies, xml ) Need Help??
Contributed by Anonymous Monk on Sep 03, 2000 at 23:55 UTC
Q&A  > arrays

Answer: How do I insert an element into an arbitrary (in range) array index?
contributed by Russ

Use splice with 0 for the length argument.

my @R = (1,2,3,4,5,6,7,8,9); splice @R, 1, 0, 'Test'; print "@R\n";
prints: 1 Test 2 3 4 5 6 7 8 9
Answer: How do I insert an element into an arbitrary (in range) array index?
contributed by jreades

Algorithms with Perl (call it the Wolf book) covers just this issue in one of the early chapters

Basically, you have two choices: an array or a linked list.

The choice between these two will depend on, primarily, the size of the list.

Splice(): As lhoward indicated, inserting a value at an aribtrary index using splice is expensive.

The time for each splice() increases at a constant rate as your list grows in size. With splice(), although from the user end it looks like you just inserted something, to memory you were creating and manipulating multiple arrays (basically, a one or more copies of your original array) in memory.

This may not be a problem if your array is 10, 20, or even 100 items, but if it's 10,000 or 100,000 you're going to see a real performance hit. This brings us to...

Linked Lists: perhaps the easiest (and probably least accurate) way to describe it is to say that linked lists are array-like.

The basic principle is that you have a value (call it 'x') and a pointer (reference, call it 'a') to the next item (call it 'y') in the linked list (assuming a simple linked list).

So a(x) -> b(y) -> c(z) and so on...

Suddenly, we've radically altered the tradeoffs... To add a value q between x and y I just need to change the pointers as follows:

a(x) -> e(q) -> b(y) -> c(z) and so on...

The cost of inserting values at arbitrary locations is reduced to, I believe, O(1) -- I can insert anywhere in the list just by rearranging the pointers and that is essentially a constant time operation regardless of how big my list is...

Of course, now I might have some trouble *finding* the element, but that's another question entirely...

Answer: How do I insert an element into an arbitrary (in range) array index?
contributed by lhoward

By insert I assume you mean "put between 2 current array elements, shifting down the later ones to make room".

The unfortunate answer is that you can't do this efficiently using native perl arrays. The code to do it isn't long or complex, but as a consequence of the design of perl's arrays (which makes them so efficient at so many other operations) sacrifices had to be made. One of those is that inserting in the middle of an array is "slow" — the time it takes to do it depends on how many elements are already in the array. (In big-O notation, the operation is said to be O(n).).

my @array = qw(3 1 4 1 5 9 2 6 5 4); my $offset = 5; my $value = 'abc'; print "before: @array\n"; splice @array, $offset, 0, $value; print " after: @array\n";
Answer: How do I insert an element into an arbitrary (in range) array index?
contributed by Jorge_de_Burgos

#!/usr/bin/perl -w use warnings; use strict; use 5.10.0; my @in_array = qw(A B C E F G); my @out_array; my $insert = 'D'; push @out_array, @in_array[0..2], $insert, @in_array[3..5]; say join (', ', @in_array); say join (', ', @out_array); exit;
I think this approach is the most human-readable. By the way, it doesn't use splice with its performance issues.
Answer: How do I insert an element into an arbitrary (in range) array index?
contributed by Denis.Beurive

Hello! You can use this function :

sub arrayInsertAfterPosition { my ($inArray, $inPosition, $inElement) = @_; my @res = (); my @after = (); my $arrayLength = int @{$inArray}; if ($inPosition < 0) { @after = @{$inArray}; } else { if ($inPosition >= $arrayLength) { $inPosition = $arrayLen +gth - 1; } if ($inPosition < $arrayLength - 1) { @after = @{$inArray}[($ +inPosition+1)..($arrayLength-1)]; } } push (@res, @{$inArray}[0..$inPosition], $inElement, @after); return @res; } my @tab = qw(A B C D E); my @res = (); @res = arrayInsertAfterPosition (\@tab, -1, 'Test'); print join(', ', @res) . "\n"; @res = arrayInsertAfterPosition (\@tab, 0, 'Test'); print join(', ', @res) . "\n"; @res = arrayInsertAfterPosition (\@tab, 1, 'Test'); print join(', ', @res) . "\n"; @res = arrayInsertAfterPosition (\@tab, 2, 'Test'); print join(', ', @res) . "\n"; @res = arrayInsertAfterPosition (\@tab, 3, 'Test'); print join(', ', @res) . "\n"; @res = arrayInsertAfterPosition (\@tab, 4, 'Test'); print join(', ', @res) . "\n"; @res = arrayInsertAfterPosition (\@tab, 5, 'Test'); print join(', ', @res) . "\n";

The result is :

Test, A, B, C, D, E A, Test, B, C, D, E A, B, Test, C, D, E A, B, C, Test, D, E A, B, C, D, Test, E A, B, C, D, E, Test A, B, C, D, E, Test

Please (register and) log in if you wish to add an answer

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others wandering the Monastery: (8)
    As of 2016-07-26 09:36 GMT
    Find Nodes?
      Voting Booth?
      What is your favorite alternate name for a (specific) keyboard key?

      Results (234 votes). Check out past polls.