Link to home
Start Free TrialLog in
Avatar of OmniUnlimited
OmniUnlimitedFlag for United States of America

asked on

Rearrange Arrays in PHP

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!
SOLUTION
Avatar of Ess Kay
Ess Kay
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I'm curious what the purpose of this is.  It doesn't change the amount of code required to access them.
I think you're looking for what is known as matrix inversion.  If I get a chance I'll show you a code sample.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of OmniUnlimited

ASKER

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?
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.
Avatar of duncanb7
duncanb7

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
@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?
thanks for your reminder, sorry typing mistake, "straight forward"
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.
@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.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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

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.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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. :)
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 :-)
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!
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
@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. :)
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
@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
Sure thing buddy.

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