I have a list of colors in $colors and want to remove certain colors if another color is present in the loop.
For example: If the color blue is part of the loop, I want to remove the color dark-blue from the list.
I tried to check if the color blue is in the array. But I'm not sure how and how I can ignore it after that in the foreach loop.
This is my current code:
<?php
$colors = $product->get_attribute('colors');
if( strpos($colors, 'blue') !== false ) :
$has_blue = true;
else :
$has_blue = false;
endif;
foreach ( $colors as $color ) :
// content
endforeach;
?>
I think my approach isn't the best practice method because I need to add a if/else statement for every color.
Is there a better way to do this?
Here's the array of $colors (one item):
array(6) {
[0]=>
object(WP_Term)#27294 (10) {
["term_id"]=>
int(85)
["name"]=>
string(5) "Blue"
["slug"]=>
string(5) "blue"
["term_group"]=>
int(0)
["term_taxonomy_id"]=>
int(85)
["taxonomy"]=>
string(7) "color"
["description"]=>
string(0) ""
["parent"]=>
int(0)
["count"]=>
int(720)
["filter"]=>
string(3) "raw"
}
CodePudding user response:
You are checking it the wrong way. There are still some things missing in your question. First of all what is the data type of this?
$colors = $product->get_attribute('colors');
Is it an array? Or some data loop? Data loops are pretty much same as array. Is it a multidimensional array? If not then use in_array() function to check for the color.
In this way you can deduct the use of foreach. If it is a multidimensional array then you have put the if conditionals inside foreach loop like this:
foreach ( $colors as $color ) :
if( strpos($color, 'blue') !== false ) :
$has_blue = true;
else :
$has_blue = false;
endif;
endforeach;
If you need anything else please elaborate your question some more.
CodePudding user response:
You can create a FilterIterator. And because name in your example is capitailized I use stripos instead of strpos.
class ColorFilter extends FilterIterator
{
private $_filter;
public function __construct($colors, $filter)
{
parent::__construct(new ArrayIterator($colors));
$this->_filter = $filter;
}
public function accept()
{
$color = $this->getInnerIterator()->current();
return stripos($color->name, $this->_filter) === false;
}
}
foreach(new ColorFilter($colors, 'blue') as $filted_color)
{
}
CodePudding user response:
I think you can filter the colors dynamically like this:
$colors_3 = [
0 => (object) [
"name" => "Blue",
],
1 => (object) [
"name" => "Dark Blue",
],
2 => (object) [
"name" => "Red",
],
3 => (object) [
"name" => "Dark Red",
],
4 => (object) [
"name" => "Dark Orange",
],
5 => (object) [
"name" => "Purple",
],
];
function filter_colors($colors)
{
$filter_me = [];
$filtered_colors = [];
foreach ($colors as $color) {
$parts = explode(" ", $color->name);
if (count($parts) == 1) {
$filter_me[] = $color->name;
}
}
foreach ($colors as $color) {
$parts = explode(" ", $color->name);
foreach ($parts as $part) {
if (in_array($part, $filter_me)) {
if (count($parts) == 1) {
break;
}
continue 2;
}
}
$filtered_colors[] = $color;
}
return $filtered_colors;
}
print_r(filter_colors($colors_3);
We get a filtered array:
Array
(
[0] => stdClass Object
(
[name] => Blue
)
[1] => stdClass Object
(
[name] => Red
)
[2] => stdClass Object
(
[name] => Dark Orange
)
[3] => stdClass Object
(
[name] => Purple
)
)
If this doesn't work for some reason with the real data please update your question to include more test data.
