PHP sort an array of hyperlinks by link text - php

I have an array of hyperlinks being generated from ab object for display on a page. The link text is all that is displayed on the page. I need to sort the hyperlinks/link text alphabetically.
Here is what I have:
foreach ($value as $key1 => $value1) {
if ($key1 == 'id') {
$id = $value1;
}
if ($key1 == 'name') {
$link = '' . $value1 . '<br>';
array_push($stack, $link);
}
}
asort($stack);
print_r($stack);
The asort call on $stack does not sort the array by link text.
I think this may call for a regexp on the subset of the hyperlink string in the array, and then a string compare and switch in the array, but am at a loss on how to do that in PHP.
Any ideas much appreciated.

According to the code given, the link text is what's in $value1. So you can sort based on that.
Assuming that the link text can be used as an array key (doesn't contain invalid key characters) you can add them to an array as such: $links[$value1] = '' . $value1 . '<br>'; and then sort them by key ksort($links);

I suspect that id is unique. So first create a nice key/value array then sort it. Then fill stack with sorted hyperlinks
$links = array();
foreach ($value as $key1 => $value1)
{
if ($key1 == 'id') {
$id = $value1;
}
if ($key1 == 'name') {
$links[$id] = $value1;
}
}
asort($links);
print_r($links);
foreach($links as $id=>$name)
{
$link = '' . $name. '<br>';
array_push($stack, $link);
}

Off the top of my head, something like this should work:
$keys = asort(array_keys($stack));
$sorted = array();
foreach ($keys as $key) {
$sorted[$key] = $stack[$key];
}

sorting the array could be done like so:
array_sort($value, 'linkname', SORT_ASC)
and then parse it within the foreach loop. More information about sorting an array from a query by a specific key could be found in the php manual: sort

Related

concatinating two array elements with a string within a foreach loop

I am trying to combine two array elements with the string "OR" and create one string of elements.
The array looks like this:
$myarray = array(2282396,1801345)
This is the code i have used.
$bool = ' OR ';
foreach($myarray as $element){
echo $element .= $bool;
}
I trying to get this output after looping using a foreach loop.
2282396 OR 1801345
However, the output i get looks like this:
2282396 OR 1801345 OR
How do i get rid of the 'OR' after the second element? Thanks in advance
You have to check if you're in the first/last iteration or not.
$first = true;
$bool = ' OR ';
foreach ($myarray as $element) {
if (!$first) {
echo $bool;
}
echo $element;
$first = false;
}
If your array is indexed by numeric indexes 0-x, you an use
$bool = ' OR ';
foreach ($myarray as $key => $element) {
if ($key > 0) {
echo $bool;
}
echo $element;
}
Use implode as:
echo implode(" OR ", $myarray);
Documentation implode
Live example: 3v4l

Arrays and nested foreach

I have two array output (using preg_match_all), for example: $name[1] and $family[1].
i need to put these arrays together, and i use foreach as this:
foreach( $name[1] as $name) {
foreach( $family[1] as $family) {
echo $name.$family.'<br />';
}
}
but it don't work.
(each foreach loop works separately)
Assuming they have matching keys for the loop:
foreach( $name as $key => $value) {
echo $value[$key] . $family[$key] . '<br />';
}
This will go through each match for $name and print it out, and then print out the corresponding $family with it. I don't think you want to hardcode [1].
If you do, I'm a little confused and would like to see a var_dump of both $name and $family for clarification.
$together= array();
foreach( $name as $key => $n) {
$tuple= array('name'=>$name[$key],'family'=>$family[$key]);
$together[$key]= $tuple;
}
foreach( $together as $key => $tuple) {
echo "{$tuple['name']} {$tuple['family']}<br />";
}
Use array_combine():
Creates an array by using the values from the keys array as keys and
the values from the values array as the corresponding values.
PHP CODE:
$nameFamilly=array_combine($name[1] , $family[1]);
foreach( $nameFamilly as $name=>$familly) {
echo $name.$family.'<br />';
}

php: foreach() how to assign to two variables

function example()
{
foreach ($choices as $key => $choice) { # \__ both should run parallel
foreach ($vtitles as $keystwo => $vtitle) { # /
$options .= '<option value="'. check_plain($key) .'" title="' . $vtitle . '"' . $selected
.'>'. check_plain($choice) .'</option>';
} // end of vtitle
} // end of choice
return $options;
}
Answers to some of the below questions and what I am trying to achieve.
Array $choices is not numerically indexed.
Array $vtitle is numerically indexed.
They won't be shorter than each other as I have code which will take care of this before this code runs.
I am trying to return $options variable. The issue is that $choices[0] and $vtitle[0] should be used only once. Hope I was able to express my problem.
I do not want to go through the $vtitles array once for each value in $choices.
#hakre: thanks I have nearly solved it with your help.
I am getting an error for variable $vtitle:
InvalidArgumentException: Passed variable is not an array or object, using empty array
instead in ArrayIterator->__construct() (line 35 of /home/vishal/Dropbox/sites/chatter/sites
/all/themes/kt_vusers/template.php).
I am sure its an array this is the output using print_r
Array ( [0] => vishalkh [1] => newandold )
What might be going wrong ?
The below worked for me , thank you hakre
while
(
(list($key1, $value1) = each($array1))
&& (list($key2, $value2) = each($array2))
)
{
printf("%s => %s, %s => %s \n", $key1, $value1, $key2, $value2);
}
It does not work the way you outline with your pseudo code. However, the SPL offers a way to iterate multiple iterators at once. It's called MultipleIterator and you can attach as many iterators as you like:
$multi = new MultipleIterator();
$multi->attachIterator(new ArrayIterator($array1));
$multi->attachIterator(new ArrayIterator($array2));
foreach($multi as $value)
{
list($key1, $key2) = $multi->key();
list($value1, $value2) = $value;
}
See it in action: Demo
Edit: The first example shows a suggestion from the SPL. It has the benefit that it can deal with any kind of iterators, not only arrays. If you want to express something similar with arrays, you can achieve something similar with the classic while(list()=each()) loop, which allows more expressions than foreach.
while
(
(list($key1, $value1) = each($array1))
&& (list($key2, $value2) = each($array2))
)
{
printf("%s => %s, %s => %s \n", $key1, $value1, $key2, $value2);
}
Demo (the minimum number of elements are iterated)
See as well a related question: Multiple index variables in PHP foreach loop
you can't do it in foreach loop in general case. But you can do it like this in PHP5:
$obj1 = new ArrayObject($arr1);
$it1 = $obj1->getIterator();
$obj2 = new ArrayObject($arr2);
$it2 = $obj2->getIterator();
while( $it1->valid() && $it2->valid())
{
echo $it1->key() . "=" . $it1->current() . "\n";
$it1->next();
echo $it2->key() . "=" . $it2->current() . "\n";
$it2->next();
}
In older versions of PHP it will be like this:
while (($choice = current($choices)) && ($vtitle = current($vtitles))) {
$key_choice = key($choices);
$key_vtitle = key($vtitles);
next($choices);
next($vtitles);
}
Short Answer, no.
What you can do instead is:
foreach ($array1 as $k => $v)
performMyLogic($k, $v);
foreach ($array2 as $k => $v)
performMyLogic($k, $v);
If the keys are the same, you can do this:
foreach ($choices as $key => $choice) {
$vtitle = $vtitles[$key];
}
You may have to refigure your logic to do what you want. Any reason you can't just use 2 foreach loops? Or nest one inside the other?
EDIT: as others have pointed out, if PHP did support what you're trying to do, it wouldn't be safe at all.. so it's probably a good thing that it doesn't :)
Maybe you want this:
//get theirs keys
$keys_choices = array_keys($choices);
$keys_vtitles = array_keys($vtitles);
//the same size I guess
if (count($keys_choices) === count($keys_vtitles)) {
for ($i = 0;$i < count($keys_choices); $i++) {
//First array
$key_1 = $keys_choices[$i];
$value_1 = $choices[$keys_choices[$i]];
//second_array
$key_2 = $key_vtitles[$i];
$value_2 = $vtitles[$keys_vtitles[$i]];
//and you can operate
}
}
But this will work if size is the same. But you can change this code.
You need to use two foreach loops.
foreach ($choices as $keyChoice => $choice)
{
foreach ($vtitles as $keyVtitle => $vtitle)
{
//Code to work on values here
}
}

Anything to attend when changing values in a multidimensional foreach() loop?

I got a site that executes the following code
$keywords = ($_SESSION[$_POST['ts']]);
print_r($keywords);
foreach ($keywords as $keyword) {
foreach ($keyword['whitelist'] as $entry) {
foreach ($_POST as $key => $value) {
if ($key == $entry['encoded_url']) {
$entry['ignore'] = $value;
$decodedURL = $this->base64->url_decode($entry['encoded_url']);
if ($value == 'noignore') {
echo "found!<br />";
$this->blacklist_model->remove($decodedURL);
$html = $this->analyse->getHTML($decodedURL);
$entry['html'] = $html[0];
$entry['loading_time'] = $html[1];
}
if($value == 'alwaysignore') {
$this->blacklist_model->add($decodedURL);
}
}
}
}
}
print_r($keywords);
The output looks like this:
http://pastebin.com/B3PtrqjB
So, as you see, there are several "found!"s in the output, so the if clause actually gets executed a few times and I expected the second array to contain new data like 'html', but, as you see, nothing changes. Is there anything to attend when changing values in multidimensional foreach() loops?
foreach creates a copy of the array and loops through that. Modifying values doesn't work.
You can get around this, though, by using references.
foreach ($keywords as &$keyword) {
foreach ($keyword['whitelist'] as &$entry) {
foreach ($_POST as $key => &$value) {
...
}
}
}
With that you can modify $value and it WILL affect the original array.
You suppose to change the Original array.
$entry is just an instance / unconnected node.
you need to change $keywords, and not its on the fly created nodes.

PHP: high depth array, how do return current key name?

I have a huge array from a json_decode result (assoc set to true) and have the following code to check if (one of the arrays within, a random serial) has the key 'set_true'
$out = "";
foreach ($array as $sub) {
//$out[] = $sub['set_true'];
if (in_array($sub['set_true'], $sub) && $sub['set_true'] == '1' ) {
$out[] = 'User: ' . $sub . ' has set_true = 1';
}
}
That code lists all the users with that array key set to 1, but $sub returns 'array' and not the current key I'm on! (the random serial)
How do I return it?
If you are looping through an array with foreach, and want to know the key you're currently on in the loop, you can use this syntax :
foreach ($array as $key => $value) {
// $key contains the name of the current key
// and $value the current value
}
What's up with your in_array call? I don't think that is correct. Why do you look for $sub in $sub?
I think you mean:
$out = "";
foreach ($array as $key => $sub) {
if (array_key_exists('set_true', $sub) && $sub['set_true'] == '1' ) {
$out[] = 'User: ' . $key . ' has set_true = 1';
}
}

Categories