Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Multi Array Conditional Sorting 1

Status
Not open for further replies.

Extension

Programmer
Nov 3, 2004
311
CA
Hi,

I'm trying to sort a "conditional" multidim-array

Here's the code + array

Code:
$Pages = array( 
				
    1 => array (    
                "Title" => "Title 1",
				"Words" => "aber,abom,dee" ),
				
	2 => array (    
                "Title" => "Title 2",
				"Words" => "abdo,text,type" ),
);

Code:
	foreach ($Pages as $key=>$Page) {
	
		$myWords = explode(",", $Page['Words']);
		array_multisort($myWords, SORT_ASC);
		
		foreach ($myWords as $myWord) {
				$myFirstLetter = $myWord{0};
				if ($myFirstLetter == "a") {
					echo "<a href=\"[URL unfurl="true"]http://something.come\">{$myWord}</a>[/URL] <br>";
				}
		}
	}

So I would like to sort the strings that met the conditions (ASC)

I obviously get this right now:
aber
abom
abdo

instead of
abdo
aber
abom

Any input would be appreciated...
 
you might want to look at how you originally shaped the array - it's often better to go back to that first design choice when you start getting bogged down in outputting the array.

anyway... i don't think that this is a job of array_multisort as the words element is not, itself an array and that's what you want.

this code does what you want it to do. i've spaced it out to make it easier to read.
Code:
<?
$Pages = array(
                
    1 => array (    
                "Title" => "Title 1",
                "Words" => "aber,abom,dee" ),
                
    2 => array (    
                "Title" => "Title 2",
                "Words" => "abdo,text,type" ),
);

//first extract the Words into their own array
$arr_words = array();
//loop through the $Pages array
foreach($Pages as $val):
	//turn the string of words into an array
	$tmp_array = explode(",", $val['Words']);
	//merge the newly formed array into the holding array
	$arr_words = array_merge($arr_words,$tmp_array);
endforeach;
//perform a standard sort on the holding array (as it is now uni-dimensional)
sort($arr_words);
//you now have a sorted array of just the words

//to print out the Words conditionally
//loop through the holding array
foreach ($arr_words as $val):
	//check if the first letter is an a
	//note force to lower case to allow for user input variance
	if (strtolower(substr($val,0,1) === "a")):
		echo "$val <br/>";
	endif;
endforeach;
?>
 
Thanks jpadie.

But what if I want to print the Title from the "Pages" array ?

Code:
    echo "$val from $Pages['Title'] <br/>";

Thanks
 
change this line
Code:
$tmp_array = explode(",", $val['Words']);
to
Code:
$tmp_array = explode(",", $val['Words']). " from ".$val['Title');


 
sorry - ignore that completely. i'll post something the has a chance of working later.
 
Anyone could help me with this issue. Still haven't found a solution yet.

Thank you in advance...
 
my apologies. i remember this and thought i had posted back.

i still think your best bet is to go back to the drawing board and restructure the array from the start.

but here is some code that does what you want. you will see that it restructures the array on the fly and reuses bits from my previous post.

i can't think of a more efficient way to do what you ask from this starting point but there probably is one. also it does not work if there is a word appears in more than one title. if this is a requirement let me know and i will rethink.
Code:
<?
$Pages = array(
                
    1 => array (    
                "Title" => "Title 1",
                "Words" => "aber,abom,dee" ),
                
    2 => array (    
                "Title" => "Title 2",
                "Words" => "abdo,text,type" ),
);

foreach ($Pages as $key=>$val):
	$tmp_array = explode(",", $val['Words']);
	$tmp_array = array_flip($tmp_array);
	foreach ($tmp_array as $key=>$_val):
		$array[$key] = $val['Title'];
	endforeach;
	$tmp_array="";
endforeach;
ksort($array);
foreach ($array as $word=>$title):
	echo "$word from $title <br/>";
endforeach;
?>
 
jpadie

Thank you very much for your help. It's working perfectly. I'm new to functions such as array_flip. I read about it to get more details.

Now I feel bad to ask you another question. I tried but I could'nt succeed. If I want to use the Page (key) instead of the Title (in final array) in order to print "$word from $page" instead ?

Thanks again for your help.
 
heh, you mean a complete code solution didn't teach you how to actually modify it so you understood it? I'm shocked.
Code:
foreach ($array as $key=>$value)
{

}
[code]
Just loops through an array, setting $key to to the index value and $value to the actual value. So you need to either use page as a key, or preferably (for future code expansion) use an array of values.

In other words, redefine your structure so that your array holds both the page & the title instead of just the title, and then print out whatever you want.

As an illustration
[code]
$array[0]["title"] = "Moby Dick";
$array[0]["author"] = "Hermy";
$array[0]["page"] = 1;
$array[0]["words"][0] = "Call";
$array[0]["words"][1] = "me";
$array[0]["words"][2] = "Ishmael";

foreach ($array as $key=>$myStruct)
{
  echo "Title: ".$myStruct["title"]."<br />";
  echo "Contains words: ";
  foreach ($myStruct["words"] as $value)
  { 
    $value.' ';
  }
  echo "<br />";
  echo "On page: ".$myStruct["page"];
}

You need to define the structure & datatypes you care about... PHP is a loosely typed language, but that does not free you from the concept of a STRUCT. Once defined you need to decide how you want to use it.... in your example it sounds like if you used my above example you'd want to loop through your collection of $myStruct's and re-index them by word
Code:
foreach ($array as $key=>$myStruct)
{
  foreach ($myStruct["words"]=>$word)
  {
    if ($wordIndexed[$word])
    {
      if (!(in_array($array[$key], $wordIndexed))
      {
        $wordIndexed[$word][] = $array[$key];
      }
    }
  }
}

Then looping over your new $wordIndexed array should make your task trivial. Note the use of the empty brackets []... this automatically appends onto a numerically indexed array.

Also take note of in_array(), the check there verifies that you haven't already appended the current structure to this wordIndex... i.e. Call me Ishmael, cause my name is Ishmael would only be added to the $wordIndexed["me"] section one time.

Lot of information in those examples, so please ask for clarification if anything didn't make sense and I'll do my best to come back.
 
* I mean the $wordIndexed["Ishmael"] section, not hte $wordIndexed["me"] section
 
@Extension

below is the code with inline comments. key thing is to get comfortable with the foreach construct.

Code:
<?
$Pages = array(
                
    1 => array (    
                "Title" => "Title 1",
                "Words" => "aber,abom,dee" ),
                
    2 => array (    
                "Title" => "Title 2",
                "Words" => "abdo,text,type" ),
);

//this takes the Pages array and
//iterates through it key by key
foreach ($Pages as $key=>$val):
	//take the string contained in the array element
	//and split the string into an array (by comma)
    $tmp_array = explode(",", $val['Words']);
	//this transforms the keys and the values of the array
	//so that the keys become the arrays and vice versa
    $tmp_array = array_flip($tmp_array);
	//iterate through the newly flipped array
	//and assign the title and the
	//page number as a sub-array
    foreach ($tmp_array as $_key=>$_val):
        $array[$_key] = array("Title"=>$val['Title'], "Page"=>$key);
    endforeach;
    $tmp_array="";
endforeach;
ksort($array);
foreach ($array as $word=>$subarray):
    echo "$word from {$subarray['Title']} on page {$subarray['Page']}<br/>";
endforeach;

?>
 
jpadie
Thank you very much for the clear explanations.
You're help was really appreciated.

I was able to do some little tweaks in order to push more values into the tmp_array.

Thanks again.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top