Jump to content

Recommended Posts

Is it posible to make a foreach loop and use where something equals somemething condition in PHP?
 
E.g. I have a code like:
 

 

    <?php foreach($parents as $parent) : ?>
      echo $parent->title;
    <?php endforeach; ?>
 

 

 
And I would like to have something like:
 

 

    <?php foreach($parents as $parent, where $parent->type = 'submenu1') : ?>
      echo $parent->title;
    <?php endforeach; ?>
 

 

 
So, it will filter stuff on the fly.
 
The reason behind it is that I can do only one mysql query and grab all submenus stuff and then in php code loop just one object instead of e.g. 20 or more.
 
how to do such thing and implement where filter in foreach loop?
Link to comment
https://forums.phpfreaks.com/topic/275592-foreach-and-where-combined-in-php/
Share on other sites

If the original parents array is the result of a SQL query, do the filtering in the query

I cannot do 20 or 50 queries and send them to view. thats crazy ;D I can of ourse do the if condition inside foreach loop but I prefer some more elegant and playfuly-clever solution

Edited by ementalis

I can of ourse do the if condition inside foreach loop but I prefer some more elegant and playfuly-clever solution

<?php

class ConditionalIterator implements Iterator {
	private $mList;
	private $mKeys;
	private $mKeyIdx;

	private $mFieldToCheck;
	private $mFieldValue;

	public function __construct($list, $field, $value){
		$this->mList = $list;
		$this->mKeys = array_keys($list);

		$this->mFieldToCheck = $field;
		$this->mFieldValue = $value;

		$this->rewind();
	}
	
	private function getNextMatchingKeyIndex($s){
		for (; $s<count($this->mKeys); $s++){
			$k = $this->mKeys[$s];
			$v = $this->mList[$k];

			if (is_array($v) && isset($v[$this->mFieldToCheck])){
				if ($v[$this->mFieldToCheck] == $this->mFieldValue){
					return $s;
				}
			}
			else if (is_object($v) && isset($v->{$this->mFieldToCheck})){
				if ($v->{$this->mFieldToCheck} == $this->mFieldValue){
					return $s;
				}
			}
		}

		return false;
	}

	public function rewind(){
		$this->mKeyIdx = $this->getNextMatchingKeyIndex(0);
	}

	public function current(){
		$key = $this->key();
		return $this->mList[$key];
	}

	public function key(){
		return $this->mKeys[$this->mKeyIdx];
	}

	public function next(){
		$this->mKeyIdx = $this->getNextMatchingKeyIndex($this->mKeyIdx+1);
	}

	public function valid(){
		return $this->mKeyIdx !== false;
	}
}

$a = new stdclass();
$a->type = 'a';
$a->name = 'one';
$b = new stdclass();
$b->type = 'b';
$b->name = 'two';
$c = new stdclass();
$c->type = 'c';
$c->name = 'three';

$ap = new stdclass();
$ap->type = 'a';
$ap->name = 'four';
$bp = new stdclass();
$bp->type = 'b';
$bp->name = 'five';
$cp = new stdclass();
$cp->type = 'c';
$cp->name = 'six';

$list = array($a, $b, $c, $ap, $bp, $cp);

foreach (new ConditionalIterator($list, 'type', 'b') as $k=>$v){
	var_dump($k, $v);
}
echo 'Done!';


 

There ya go. Complex, hard to understand, and in complete violation of the KISS principal, just like you ordered.

Edited by kicken
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.