4

I have an associative array of the form:

$input = array("one" => <class object1>,
               "two" => <class object2,
               ... //and so on);

The keys of $input are guaranteed to be unique. I also have a method called moveToHead($key) which moves the $input[$key] element to the 0th location of this associative array. I have few questions:

  1. Is it possible to determine the index of an associative array?
  2. How to move the array entry for corresponding $key => $value pair to the index 0 and retaining the $key as is?
  3. What could be the best possible way to achieve both of the above points?

I was thinking to do array_flip for 2nd point (a sub solution), but later found out that array_flip can only be done when array elements are int and string only. Any pointers?

hakre
  • 193,403
  • 52
  • 435
  • 836
Ankit Garg
  • 709
  • 1
  • 11
  • 26

4 Answers4

1

The "index" of an associative array is the key. In a numerically indexed array, the "key" is the index number.

EDIT: I take it back. PHP's associative arrays are ordered (like Ordered Maps in other languages).

But perhaps what you really want is an ordered array of associative arrays?

$input = array(array("one" => <class object1>),
               array("two" => <class object2>)
               //...
         );
grammar31
  • 2,000
  • 1
  • 12
  • 17
  • PHP's arrays are ordered hashtables, so order is meaningful. Similar to what you have in other language with `ordered_map` etc ;) – NikiC Jul 20 '12 at 16:48
  • PHP array keys _are_ ordered though! That's why we have functions like `ksort()` – Michael Berkowski Jul 20 '12 at 16:48
  • I do have the implementation as described by @grammar31, but moving searching, deleting, moving all operations will have O(n) time complexity. However, I was thinking to do the same in O(1). If it is not possible in O(1), can we reduce the constant for linear time required? – Ankit Garg Jul 20 '12 at 16:52
1

With a function called array_keys you can determine the index of a key:

$keys = array_flip(array_keys($input));
printf("Index of '%s' is: %d\n", $key, $keys[$key]);

To insert an array at a certain position (for example at the beginning), there is the array_splice function. So you can create the array to insert, remove the value from the old place and splice it in:

$key = 'two';
$value = $input[$key];
unset($input[$key]);    
array_splice($input, 0, 0, array($key => $value));

Something similar is possible with the array union operator, but only because you want to move to the top:

$key = 'two';
$value = $input[$key];
unset($input[$key]);
$result = array($key => $value) + $input;

But I think this might have more overhead than array_splice.

hakre
  • 193,403
  • 52
  • 435
  • 836
  • array_unshift - again O(n) time complexity due to reindexing involved. – Ankit Garg Jul 20 '12 at 17:05
  • I changed that code, I saw that it did too much. However no idea if you can really go away from O(n). – hakre Jul 20 '12 at 17:07
  • good thought, I just missed on that one. I will try this on my class objects and will let you know the results. thnx :) – Ankit Garg Jul 20 '12 at 17:14
  • 1
    Edited as I saw somebody else had the array union operator as well and made the array_splice example more prominent, I think it's a pretty good variant. – hakre Jul 20 '12 at 17:15
  • the array_splice thing is replacing the key with "0", but the second union operator is working just fine. – Ankit Garg Jul 20 '12 at 17:27
  • Right, the key is not taken over, I have overlooked that ([demo](http://codepad.org/85N9N8gz)). Please see as well: [In PHP, how do you change the key of an array element?](http://stackoverflow.com/questions/240660/in-php-how-do-you-change-the-key-of-an-array-element) – hakre Jul 21 '12 at 11:03
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/14218/discussion-between-ankit-garg-and-hakre) – Ankit Garg Jul 21 '12 at 14:45
1

Here's what I came up with:

$arr = array('one' => 'Value1', 'two' => 'Value2', 'three' => 'Value3');

function moveToHead($array,$key) {
   $return = $array;
   $add_val = array($key => $return[$key]);
   unset($return[$key]);
   return $add_val + $return;
}

print_r(moveToHead($arr,'two'));

results in

Array
(
    [two] => Value2
    [one] => Value1
    [three] => Value3
)

http://codepad.org/Jcb6ebxZ

Brian Glaz
  • 15,468
  • 4
  • 37
  • 55
0

You can use internal array pointer functions to do what you want:

$input = array(
    "one"   => "element one",
    "two"   => "element two",
    "three" => "element three",
);
reset($input); // Move to first element.
echo key($input); // "one"

You can unset the element out and put it in the front:

$input = array(
    "one"   => "element one",
    "two"   => "element two",
    "three" => "element three",
);
$key = "two";
$element = $input[$key];
unset($input[$key]);
// Complicated associative array unshift:
$input = array_reverse($input);
$input[$key] = $element;
$input = array_reverse($input);
print_r($input);
Waleed Khan
  • 11,426
  • 6
  • 39
  • 70
  • Yes, I'm also doing the same thing, but the whole point is, this takes two array_reverse function calls. array_reverse itself run in O(n) time complexity. – Ankit Garg Jul 20 '12 at 17:01