Solved

Rearrange Arrays in PHP

Posted on 2014-01-02
23
348 Views
Last Modified: 2014-01-06
Happy New Year Experts!

I hope this question finds you all well and ready for a fantastic new year.

I'd like to start out simple this year (simple at least to you PHP geniuses out there.)

I have a multidimentional associative array, let's call it $A.  This array can be accessed by using two keys such as $A[$key1][$key2].

Right now, the order of the elements goes something like this:

$A['first']['e1']
$A['first']['e2']
$A['first']['e3']
$A['first']['e4']
$A['first']['e5']
$A['first']['e6']
$A['second']['e1']
$A['second']['e2']
$A['second']['e3']
$A['second']['e4']
$A['second']['e5']
$A['second']['e6']
$A['third']['e1']
$A['third']['e2']
$A['third']['e3']
$A['third']['e4']
$A['third']['e5']
$A['third']['e6']
...etc.

I would like to create a new array grouping all the "e1" elements together, then the "e2" elements and so on, so that the new array would look something like the following:

$NewArray['e1'] = array($A['first']['e1'], $A['second']['e1'], $A['third']['e1'], etc...);
$NewArray['e2'] = array($A['first']['e2'], $A['second']['e2'], $A['third']['e2'], etc...);
$NewArray['e3'] = array($A['first']['e3'], $A['second']['e3'], $A['third']['e3'], etc...);
etc...

What is the simplest, most elegant and efficient solution to this?

Thanks!
0
Comment
Question by:OmniUnlimited
  • 5
  • 5
  • 5
  • +3
23 Comments
 
LVL 15

Assisted Solution

by:Ess Kay
Ess Kay earned 125 total points
ID: 39752446
just run two for loops


heres the pseudocode

Array NewArray[$A.size]

for i = 0; i< $A.size ; i++

    for j = 0; j< $A[i].size ; j++
       NewArray [i].add   $A[i][j]

Open in new window

0
 
LVL 82

Expert Comment

by:Dave Baldwin
ID: 39752476
I'm curious what the purpose of this is.  It doesn't change the amount of code required to access them.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39752576
I think you're looking for what is known as matrix inversion.  If I get a chance I'll show you a code sample.
0
 
LVL 13

Assisted Solution

by:duncanb7
duncanb7 earned 125 total points
ID: 39752717
Probably, you might need to do several foreach loop to get your target key of  the multi-dimension array, I have done this before and the following code is just for your
reference and testing only since I am not fully testing the code in 100%, You need to do the rest for testing and checking the code.

Hope understand your question completely,if not please pt it out.

Duncan

<?php
$A['first']['e1']=1;
$A['first']['e2']=2;
$A['first']['e3']=3;
$A['first']['e4']=4;
$A['first']['e5']=5;
$A['first']['e6']=6;
$A['second']['e1']=7;
$A['second']['e2']=8;
$A['second']['e3']=9;
$A['second']['e4']=10;
$A['second']['e5']=11;
$A['second']['e6']=12;
$A['third']['e1']=13;
$A['third']['e2']=14;
$A['third']['e3']=15;
$A['third']['e4']=16;
$A['third']['e5']=17;
$A['third']['e6']=18;

//Define what keys you want to extract
$NewArray=array("e1"=>array(),"e2"=>array(),"e3"=>array());

foreach (array_keys($NewArray) as $key => $val){
  foreach ($A as $key => $element){
  if (is_array ($element)) { 
    $tmp= $key;
    foreach ($element as $key => $element){
    if( $key==$val)array_push($NewArray[$val],$A[$tmp][$key]);
   }
  }
 }
}
print_r($NewArray['e1']);
print_r($NewArray['e2']);
print_r($NewArray['e3']);

?>

Open in new window

0
 
LVL 17

Author Comment

by:OmniUnlimited
ID: 39752971
Thank you Experts for your responses.

@esskayb2d: It doesn't appear to me that you are a PHP expert.  How can you assure me that your method is the most effective and efficient solution in PHP?

@Dave Baldwin:  Forgive me, but due to previous interactions that we have had, I am a little gun shy.  In both this and the previous question you were not of agreement to doing what I was proposing in the first place.  While I certainly respect your opinion, this does not change in any way my need to have a solution to my question.  Let me propose a question to you: why do you post on a question you do not feel like helping with?

@Ray Paseur™:  Ray, it is always good to hear from you.  I am sure that if anyone knows of the most efficient way of doing this, it would be you.  Thank you for your assistance.

@duncanb7:  Thank you for your solution.  What are your claims to its efficiency over other techniques?
0
 
LVL 82

Expert Comment

by:Dave Baldwin
ID: 39752988
I'm often interested in finding out why people are doing things.  I often learn things.  Why do you expect that everyone will agree with you?  Especially if you don't want to answer questions about what you are doing.  I can't see any reason to 'give you answers' if you don't want to give any yourself.
0
 
LVL 13

Expert Comment

by:duncanb7
ID: 39753002
Dear OmniUnlimited,

I think the code I posted is just  simple foreach loop that is easier to understand and remember over other techniques,and foreach loop, array_push() and is_array() php function is
really strange forward and easier to find its syntax in search engineer or php.net.
If your requirement is getting higher or more than 2-dimension order such as 10, 100 order, that might need to do it in other techniques as inversion matrix that Ray mentioned.
The code I provided is for your question requirement only in this thread, and probably
it works

Duncan
0
 
LVL 17

Author Comment

by:OmniUnlimited
ID: 39753009
@Dave Baldwin:  Good point.  Just so you know that I don't expect everyone to agree with me, and I am not trying to stop you or anyone else from posting whatever they want to (this is after all still a free country), it's just that when I post a question it is because I am looking for a solution, not a debate.  Comments which tend to deviate from the straightest pathway towards that goal will in all likelihood be ignored by me.

@Duncan: Thank you for your well reasoned explanation.  I will test your solution along with any other solutions I receive through this thread and see how your code stands up along the rest.

and foreach loop, array_push() and is_array() php function is
really strange forward


You did mean straight forward, didn't you?
0
 
LVL 13

Expert Comment

by:duncanb7
ID: 39753016
thanks for your reminder, sorry typing mistake, "straight forward"
0
 
LVL 82

Expert Comment

by:Dave Baldwin
ID: 39753045
A cooperative response tends to make the 'experts' more interested in providing a solution.  When someone doesn't want to talk to 'us', we get less interested.  In addition, I've answered a number of questions where knowing 'why' provided a much better answer.  Your "straightest pathway" isn't always going to provide the best results.

In this question, it seems likely that just re-arranging the arrays is not the goal but the way you think you will achieve something.  You may (or may not) get a better answer if we knew what you were trying to achieve, the 'why' of what you are doing.  I know that Ray asks this question (though maybe in his own way) on many of the questions he comments on.

For what it's worth, I would probably use 'foreach' to loop thru arrays since it is intended for that purpose.  Arrays in PHP are often not in a 'numerical' order so a 'for-next' can be difficult to use.
0
 
LVL 17

Author Comment

by:OmniUnlimited
ID: 39753107
@Dave Baldwin:

A cooperative response tends to make the 'experts' more interested in providing a solution.  When someone doesn't want to talk to 'us', we get less interested.  In addition, I've answered a number of questions where knowing 'why' provided a much better answer.  Your "straightest pathway" isn't always going to provide the best results.

Agreed.  But as one 'expert' to another you should know that one has to conform to the rules imposed by those higher in authority or risk losing his position with that company.  Not saying that this is the case here, although it was on the last question.  And as an 'expert' you should respect the fact that the asker of the question may not be at liberty to disclose what it is you are requesting.

As for the 'why' to this question, you should know that this deals with an interface between two not-so-compatible systems.  We simply need to convert the output of one system to the input of the other.  Changing either system is out of the question for many reasons.

As for the foreach loop, you seem to be in agreement with Duncan that this would be the most efficient manner of handling such a conversion.

Thank you.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 82

Assisted Solution

by:Dave Baldwin
Dave Baldwin earned 125 total points
ID: 39753185
I didn't go thru his code but that was my first thought on reading your question.  The 'foreach' function is specifically designed for looping thru PHP arrays.  Even in arrays with numeric keys, it has the advantage of knowing when it has gone all the way thru an array even without you giving it a specific count.  There are a number of examples here:  http://us3.php.net/manual/en/control-structures.foreach.php

This page tells why PHP arrays are different than those in other languages: http://us3.php.net/manual/en/language.types.array.php  Arrays in most languages are based on numeric indexes.  In PHP, they are name/value pairs grouped under a single variable name.  Since PHP was originally designed to make programming web pages easier, that concept follows from the fact that HTML forms send info to the server in name/value pairs.
0
 
LVL 13

Expert Comment

by:duncanb7
ID: 39753571
Dear OmniUnlimited,

A liitle more compact code than before  as follows by taking out is_array(), $tmp and
unneccessary "{"  & "}"

$A['first']['e1']=1;
$A['first']['e2']=2;
$A['first']['e3']=3;
$A['first']['e4']=4;
$A['first']['e5']=5;
$A['first']['e6']=6;
$A['second']['e1']=7;
$A['second']['e2']=8;
$A['second']['e3']=9;
$A['second']['e4']=10;
$A['second']['e5']=11;
$A['second']['e6']=12;
$A['third']['e1']=13;
$A['third']['e2']=14;
$A['third']['e3']=15;
$A['third']['e4']=16;
$A['third']['e5']=17;
$A['third']['e6']=18;

//Define what keys you want to extract
$NewArray=array("e1"=>array(),"e2"=>array(),"e3"=>array());
foreach (array_keys($NewArray) as $key => $val)
foreach ($A as $key => $element)
foreach ($element as $key2 => $element2)
if( $key2==$val)array_push($NewArray[$val],$A[$key][$key2]);

//Print out result
print_r($NewArray['e1']);
print_r($NewArray['e2']);
print_r($NewArray['e3']);
?>

Open in new window

0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39753704
I'll have a look at this today while I drink my morning coffee, here in the snow.  But before I do, I want to make a comment about efficiency.  It does not matter.  Nothing you can do in the process of rearranging in-memory data sets will matter.  You can use a script timer to observe this fact.  The efficiencies will always be found in the I/O subsystem, and in modern web applications, that is almost always the data base.
0
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 125 total points
ID: 39753855
Please see http://www.laprbass.com/RAY_temp_omniunlimited.php and let me know if you have any questions.  As with most programming solutions, the quality of the work product is highly dependent on the quality of the test data, so if my assumptions documented in the code are incorrect, let me know a bit more about the characteristics of the real-world data.  We want to design/build/test with a data set that is as close to real-world as possible.

<?php // RAY_temp_omniunlimited.php
error_reporting(E_ALL);
echo '<pre>';


// SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28329452.html


/* DESIRED OUTPUT ORDER
 * $NewArray['e1'] = array($A['first']['e1'], $A['second']['e1'], $A['third']['e1'], etc...);
 * $NewArray['e2'] = array($A['first']['e2'], $A['second']['e2'], $A['third']['e2'], etc...);
 * $NewArray['e3'] = array($A['first']['e3'], $A['second']['e3'], $A['third']['e3'], etc...);
 *
 * ASSUMPTIONS:
 * The 'first' is a canonical representation of all of the other elements,
 * such that IF there is a 'first'=>'eX' there IS a matching 'second'=>'eX', etc.
 * This assumption means that the script can rely on 'first' to create the
 * index for the $out arrays.  If this assumption is not valid, iterative
 * methods will be needed to determine the index.
 */

// REDACTED TEST DATA
$a['first']['e1']  = 'first_e1';
$a['first']['e2']  = 'first_e2';
$a['first']['e3']  = 'first_e3';

$a['second']['e1'] = 'second_e1';
$a['second']['e2'] = 'second_e2';
$a['second']['e3'] = 'second_e3';

$a['third']['e1']  = 'third_e1';
$a['third']['e2']  = 'third_e2';
$a['third']['e3']  = 'third_e3';

// SHOW THE STARTING POINT
print_r($a);

// GET THE TOP-TIER ARRAY KEYS LIKE first, second, ...
$keys_1 = array_keys($a);

// GET THE SECOND-TIER ARRAY KEYS LIKE e1, e2, ...
$keys_2 = array_keys($a[$keys_1[0]]);

// CREATE OUR OUTPUT HERE
$out = array();

// THE SECOND-TIER KEYS BECOME KEYS IN THE OUTPUT
foreach ($keys_2 as $key_2)
{
    // EACH ELEMENT OF THE OUTPUT IS AN ARRAY
    $sub = array();

    // USING THE TOP-TIER KEYS, CREATE THE SUB-ARRAY
    foreach ($keys_1 as $key_1)
    {
        $sub[] = $a[$key_1][$key_2];
    }

    // ADD THE SUB-ARRAY TO THE KEYED LOCATION IN THE OUTPUT
    $out[$key_2] = $sub;
}

// SHOW THE WORK PRODUCT
print_r($out);

Open in new window

0
 
LVL 34

Expert Comment

by:gr8gonzo
ID: 39753967
Looks like I've mostly missed out on a lively thread. I don't have much to add (since you have two different working samples in front of you) except to add support to what both Dave and Ray have been saying.  Just a couple thoughts:

1. Don't be offended if an expert asks why. It's better that an expert asks why to better understand your situation than to offer up the wrong solution (even if it's exactly what you asked for). If someone asked you for directions on how to put a knife into an electrical socket, you would likely warn them not to do that instead of just telling them how. I've seen a lot of PHP questions come through that are pretty similar and enabling those programmers would result in bad code (even if this question doesn't fall into that category).

2. Don't be hesitant to take the correct answer from anyone, regardless of past dealings or their rank. PHP gurus can join up any day, and they may not have a lot of EE answers under their belt yet, and the quality of answers from any person can change from day to day. I might answer a question terribly one day and great the next. :)
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39754041
To second what @gr8gonzo wrote, I would only add that there are a lot of questions I've participated in where the Asker has come to the question with assumptions about part of the solution, and we do not get the information necessary to understand the assumptions.  It's hard to put all of your "deep background" thinking into writing.  But there is a thing called a code smell, and I sometimes sense a "question smell" that tells me someone has decided not to put the knife into the outlet, but is about to use the fork instead.  When we probe for more information we may find that the Asker is unaware of a lurking danger (brittle code, risk of unexpected input, risk of infinite loop, risk of run-time failure, death by electrocution) and is asking about the fork because the knife won't fit.

It's those loaded questions where the forum at EE can really add value.  That's why we may be probing for the question behind the question.

Oh, and one final thing... Test the proposed solutions before you accept :-)
0
 
LVL 17

Author Closing Comment

by:OmniUnlimited
ID: 39754499
Thank you Experts for your kind assistance and comments.

@esskayb2d: It turns out your concept did have merit in PHP.  I am therefore awarding you your share of the points.

@Dave Baldwin: In re-reading the thread (mostly spurned by gr8gonzo's comments), it seems that I may have misinterpreted your intentions, and for that I apologize.  I am under a heavy work schedule and under lots of pressure and it may be that I am just a little stressed out.  Keep asking questions.  It is what makes you great as an expert.  Thanks for the solution.

@Duncan: I appreciate the code, your effort and your solutions, however I believe that on your second (cleaned up) example if you eliminate the braces on the foreach structure you need to use the alternate control structure with (:) and endforeach.  Anyone correct me if I'm wrong. Thanks!

@Ray: If you are out in the snow, I hope you have more than that cup of coffee to keep you warm.  I will keep your comments concerning efficiency in mind.

I understand what you are saying with regards to "question smell", but do you think any of the dangers you mentioned (brittle code, risk of unexpected input, risk of infinite loop, risk of run-time failure, death by electrocution) could have occurred with this question (except in the case of extreme incompetence, and Ray, I have been around EE for several years now.  Does it really seem that I am that incompetent?)

With regards to your solution, I took your advice and tested it. The output subindexes are not correct (you have numeric values [0], [1], [2], etc. when they should be the names of the keys ['first'], ['second'], etc.) but it does not matter.  The concept you provided is sound.  I appreciate your help and assistance once again.

@gr8gonzo: Although you did not provide a solution to the question and therefore could not (at least in all fairness) be given points for doing so, I did appreciate your comments.  

I appreciate the knife in the socket allegory, howbeit I really don't think this was the case in this question (see comments above with Ray), I do see how it can be applied to others.

Please be aware that I am not averse to accepting the "correct" answer from anyone, howbeit sometimes it is difficult to determine if the answer is indeed "correct".  What happens to the code under all sorts of conditions?  Can we determine all the possibilities of its behavior?  This is why it seems to be more comforting (and whether this is all in my mind is another matter) to rely on someone that has a proven track record, and with experience such that they might have seen similar examples in real life situations more than one time, although even as you say, they may experience a "bad day".

Once again, I came to EE with a question and was looking for solutions and you gentlemen provided them.  Thanks again, and have a great day!
0
 
LVL 13

Expert Comment

by:duncanb7
ID: 39754669
Thanks for your pt, I have checked it again about taking out bracket for foreach that
is okay and working on my server since every foreach has only one single statement.
Ray's code is better than mine since he used only two foreach and  his code will cover all keys of "e1".....e10000", etc.. without typing those keys into array.

Duncan
0
 
LVL 34

Expert Comment

by:gr8gonzo
ID: 39754677
@gr8gonzo: Although you did not provide a solution to the question and therefore could not (at least in all fairness) be given points for doing so, I did appreciate your comments.  

WHAT?! No points?! No, I'm kidding. I would've objected if you -had- given me points, since I didn't do any of the work. :)
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39754903
sometimes it is difficult to determine if the answer is indeed "correct"
That's the everyday dilemma for all of us, and the answer is usually found in the quality and quantity of the test data.  More is better, usually.  And representative test cases are better, always.  In the instant case the "question smell" came from this:

$NewArray['e1'] = array($A['first']['e1'], $A['second']['e1'], $A['third']['e1'], etc...);
$NewArray['e2'] = array($A['first']['e2'], $A['second']['e2'], $A['third']['e2'], etc...);
$NewArray['e3'] = array($A['first']['e3'], $A['second']['e3'], $A['third']['e3'], etc...);

My nostrils twitched because I cannot see any added value in re-arranging the data this way.  At first glance, it looked to me like a matrix-transform question, which is a fairly common question in computer science.  But on further review there is not a true transformation from the input to the desired output.  That's not to say there is no value, but just to say that I cannot see it.  You have 100% visibility over the usefulness of the data structure, so it's your knowledge and insight that should determine the utility of the solutions.

You are correct in noting that the $NewArray "sub-arrays" (for want of a better term) have numeric indexes.  You asked for numeric indexes when you posted the question!  This is what we all wrestle with in "problem definition."  If you want to see what you asked for, run the little script below and look at the output.  It's more-or-less copied directly from the question.  The only additional contents are the data elements, with contents that can help identify the array keys in an easily visualized way.  When the script does not designate an associative array key, PHP fills in a number.

Example with an associative array key:
$x = array('key_A' => 'value_A', 'key_B => 'value_B');

Example without an array key:
$x = array('value_A', 'value_B');

Looking at the positions of the variables and the commas in $NewArray, and at the lack of the => assignment operator, it's easy to see that the question asked for sub-arrays with numeric indexes because the named array keys are not present.

<?php // RAY_temp_omniunlimited.php
error_reporting(E_ALL);
echo '<pre>';

// SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28329452.html

// ORIGINAL PROBLEM DEFINITION
$A['first']['e1'] = 'first_e1';
$A['first']['e2'] = 'first_e2';
$A['first']['e3'] = 'first_e3';

$A['second']['e1'] = 'second_e1';
$A['second']['e2'] = 'second_e2';
$A['second']['e3'] = 'second_e3';

$A['third']['e1'] = 'third_e1';
$A['third']['e2'] = 'third_e1';
$A['third']['e3'] = 'third_e1';

/*
...etc.
I would like to create a new array grouping all the "e1" elements together, then the "e2" elements and so on, so that the new array would look something like the following:
*/

$NewArray['e1'] = array($A['first']['e1'], $A['second']['e1'], $A['third']['e1'], /* etc...*/ );
$NewArray['e2'] = array($A['first']['e2'], $A['second']['e2'], $A['third']['e2'], /* etc...*/ );
$NewArray['e3'] = array($A['first']['e3'], $A['second']['e3'], $A['third']['e3'], /* etc...*/ );

/*
etc...
*/

print_r($NewArray);

Open in new window

Thanks for the points and thanks for using EE.  Best regards and best wishes for the New Year 2014, ~Ray
0
 
LVL 17

Author Comment

by:OmniUnlimited
ID: 39755698
@duncanb7: Ok, thanks for checking that out.

@gr8gonzo:  LOL!  gr8gonzo, you are a kick!

@Ray: As Homer Simpson always says, "Duoh!"

Ray, as usual, you are right on the ball.  I didn't even notice that in my original question.

Once again, thanks to all.

Best Regards,

Jason
0
 
LVL 15

Expert Comment

by:Ess Kay
ID: 39760117
Sure thing buddy.

Sorry i didnt write it out in php. My time was limited
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now