I found many question and answer about this, but not match what i need.
i think it's similar/same to this question but don't know why not working for this case. So please try before judging duplicates, thank you.
array source
$avar = array(
0 => array(1,2,3,4,5,6,7,8,9),
1 => array(10,11,12,13,14,15,16,17,7,8,9,10),
23 => array(21,22,23,4,5,6,7,11,12,13,14,15,21));
desired result
$avar = array(
0 => array(1,2,3,4,5,6,7,8,9),
1 => array(10,11,12,13,14,15,16,17),
23 => array(21,22,23));
PHP script
<?php
function super_unique($array)
{
$result = array_map("unserialize", array_unique(array_map("serialize", $array)));
foreach ($result as $key => $value)
{
if ( is_array($value) )
{
$result[$key] = super_unique($value);
}
}
return $result;
}
$result = super_unique($avar);
echo "<pre>";
print_r($result);
?>
similar question with answer but not solve my case:
How to remove duplicate values from a multi-dimensional array in PHP
PHP remove duplicate values from multidimensional array
Thank you all
$seen = array();
foreach($avar as &$entry){
$entry = array_unique(array_diff($entry,$seen));
$seen = array_merge($entry,$seen);
}
unset($entry);
var_dump($avar);
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I'm trying to get the bottom values of an array with a single condition as below :
Get all numeric values until the next value is a string then stop the instruction, and leave all other values even if they are numeric
<? php $data= [1,2,3,'web',4,5,6,'web',7,8,9]; ?>
The output will be : 7,8,9
We can try first filtering to find the first non numeric entry. Then, subset the array starting with this index. Finally, filter the subset again to remove all non numeric elements.
$data= [1,2,3,'web',4,5,6,'web',7,8,9];
$sub_data = array_filter($data, function($item) { return !is_numeric($item); });
$index = array_search(current($sub_data), $data);
$sub_data = array_slice($data, $index);
$sub_data = array_filter($sub_data, function($item) { return is_numeric($item); });
print_r($sub_data);
This prints:
Array
(
[1] => 4
[2] => 5
[3] => 6
[5] => 7
[6] => 8
[7] => 9
)
i don't know if there a specific function for it but i got the same result with this
$data= [1,2,3,'web',4,5,6,'web',7,8,9];
foreach ($data as $key => $value) {
if($value=="web"){
$x =$key;
}
}
$data = array_slice($data,$x);
print_r($data);
Output:
Array ( [0] => web [1] => 7 [2] => 8 [3] => 9 )
You can use array_reverse to get values from the array with elements in reverse order.
$reversed = array_reverse($data);
and then parse the array to stop where it gets a string
foreach($reversed as $value) {
if(is_string($value)) {
break;
}
$output[] = $value;
}
//print_r($output); // to print the output array. This will return the values like 9, 8, 7
// do a reverse again to get the values in the format you want.
$final= array_reverse($output);
print_r($final); // to print the final array. This will return the values like 7, 8, 9
Here is a DEMO
You can just pop values off the end until you get to something that isn't an int.
while (is_int($n = array_pop($data))) {
$result[] = $n;
}
This will modify the data array, so if you need to keep the original values, then do this with a copy.
The test you'll want depends on whether your example data is representative and all the numeric values you want in the array are of type int, or perhaps some might be numeric strings.
$data= [1,2,3,'web',4,5,6,'web',7,8,9];
$result = [];
for($i = count($data)-1; $i >= 0; $i++) {
// If some of the values you want might be numeric strings
// (e.g. "7") or decimals (e.g. 1.5), use this
if(!is_numeric($data[$i])) {
break;
}
// If your values will only be integer type, use this
if(!is_int($data[$i])) {
break;
}
array_unshift($result,$data[$i]);
}
// If you want the results in original order
print_r($result); // Output: [7,8,9]
// If you want the results inverted
$result = array_reverse($result);
print_r($result); // Output: [9,8,7]
Try this, here i am storing values in to an array $newArray if value is integer. if string found in value just reset the array $newArray
<?php
$data = [1,2,3,'web',4,5,6,'web',7,8,9];
$newArray = array(); // resultant array
foreach ($data as $key => $value) {
if(is_int($value)){
$newArray[] = $value;
}
else{
$newArray = array(); // reset if not integer
}
}
echo "<pre>";
print_r($newArray);
?>
DEMO
Result:
Array
(
[0] => 7
[1] => 8
[2] => 9
)
Now, you can use implode() for comma separated result, like:
echo implode(",",$newArray); // 7,8,9
Edit: (08-07-2019)
If Example:
$data = [1,2,3,'web',4,5,6,'web',7,8,9,'web'];
Code:
<?php
$data = [1,2,3,'web',4,5,6,'web',7,8,9,'web'];
$newArray = array(); // resultant array
end($data);
$keyLast = key($data); // fetches the key of the element pointed to by the internal pointer
foreach ($data as $key => $value) {
if(is_int($value) ){
$newArray[] = $value;
}
else{
if($keyLast === $key) { // if last key is string overwrite the previous array.
$newArray = $newArray;
}
else{
$newArray = array(); // reset if not integer
}
}
}
echo "<pre>";
print_r($newArray);
?>
Edit:
It's better to store all integer values into an array and then use array_slice() to get let three elements from new integer array like:
<?php
$data = [1,2,3,'web',4,5,6,'web',7,8,9,'web','web','web'];
$newArray = array(); // resultant array
foreach ($data as $key => $value) {
if(is_int($value) ){
$newArray[] = $value;
}
}
$lastThreeElement = array_values(array_slice($newArray, -3, 3, true));
echo "<pre>";
print_r($lastThreeElement);
?>
This question already has answers here:
Deleting an element from an array in PHP
(25 answers)
Closed 5 years ago.
I have an array.
$a_input = array(1,2,3,4,5)
I want to remove 1 from array . out put is :
array(2,3,4,5);
remove 2 => output:
array(1,3,4,5);
remove 3 => output :
array(1,2,4,5);
.....
how to do this with for loop ?
try this
$a_input = array(1,2,3,4,5);
$cnt=count($a_input);
for($i=0;$i<$cnt;$i++){
$remove = array($i+1);
$output1=array_diff($a_input,$remove);
var_dump("<pre>",$output1);
}
Online test
use unset.
foreach($a_input as $key => $val){
if($a_input[$key]==1) unset($a_input[$key]);
}
You can use
$array = array(1,2,3,4,5);
if (($key = array_search('1', $array)) !== false) {
unset($array[$key]);
}
Here we are searching a value in the array If it is present, then proceed to get the key at which required value is present, then unseting that value.
Try this code snippet here
<?php
ini_set('display_errors', 1);
$a_input = array(1,2,3,4,5);
$numberToSearch=2;
if(in_array($numberToSearch,$a_input))//checking whether value is present in array or not.
{
$key=array_search($numberToSearch, $a_input);//getting the value of key.
unset($a_input[$key]);//unsetting the value
}
print_r($a_input);
Output:
Array
(
[0] => 1
[2] => 3
[3] => 4
[4] => 5
)
What you need is array_filter:
$input = array(1,2,3,4,5)
$remove = 1;
$result = array_filter($input, function ($val) use ($remove) {
return $val !== $remove;
});
You need array_diff.
$a_input = array(1,2,3,4,5);
you can create new array with values like below:
$remove = array(1,2);
$result=array_diff($a_input,$remove);
output:
array(3,4,5);
Most of the programmer use this way only.And this will work for multiple elements also.
This question already has answers here:
Finding the subsets of an array in PHP
(5 answers)
Closed 7 years ago.
I will do my best to explain this idea to you. I have an array of values, i would like to know if there is a way to create another array of combined values. So, for example:
If i have this code:
array('ec','mp','ba');
I would like to be able to output something like this:
'ec,mp', 'ec,ba', 'mp,ba', 'ec,mp,ba'
Is this possible? Ideally i don't want to have duplicate entries like 'ec,mp' and 'mp,ec' though, as they would be the same thing
You can take an arbitrary decision to always put the "lower" string first. Once you made this decision, it's just a straight-up nested loop:
$arr = array('ec','mp','ba');
$result = array();
foreach ($arr as $s1) {
foreach ($arr as $s2) {
if ($s1 < $s2) {
$result[] = array($s1, $s2);
}
}
}
You can do it as follows:
$arr = array('ec','mp','ba', 'ds', 'sd', 'ad');
$newArr = array();
foreach($arr as $key=>$val) {
if($key % 2 == 0) {
$newArr[] = $val;
} else {
$newArr[floor($key/2)] = $newArr[floor($key/2)] . ',' . $val;
}
}
print_r($newArr);
And the result is:
Array
(
[0] => ec,mp
[1] => ba,ds
[2] => sd,ad
)
Have you looked at the function implode
<?php
$array = array('ec','mp','ba');
$comma_separated = implode(",", $array);
echo $comma_separated; // ec,mp,ba
?>
You could use this as a base for your program and what you are trying to achieve.
Excuse me if this question was already solved. I've searched trough the site and couldn't find an answer.
I'm trying to build a bi-dimensional array from a string. The string has this structure:
$workers="name1:age1/name2:age2/name3:age3"
The idea is to explode the array into "persons" using "/" as separator, and then using ":" to explode each "person" into an array that would contain "name" and "age".
I know the basics about the explode function:
$array=explode("separator","$string");
But I have no idea how to face this to make it bidimensional. Any help would be appreciated.
Something like the following should work. The goal is to first split the data into smaller chunks, and then step through each chunk and further subdivide it as needed.
$row = 0;
foreach (explode("/", $workers) as $substring) {
$col = 0;
foreach (explode(":", $substring) as $value) {
$array[$row][$col] = $value;
$col++;
}
$row++;
}
$array = array();
$workers = explode('/', "name1:age1/name2:age2/name3:age3");
foreach ($workers as $worker) {
$worker = explode(':', $worker);
$array[$worker[0]] = $worker[1];
}
Try this code:
<?php
$new_arr=array();
$workers="name1:age1/name2:age2/name3:age3";
$arr=explode('/',$workers);
foreach($arr as $value){
$new_arr[]=explode(':',$value);
}
?>
The quick solution is
$results = [];
$data = explode("/", $workers);
foreach ($data as $row) {
$line = explode(":", $row);
$results[] = [$line[0], $line[1]];
}
You could also use array_walk with a custom function which does the second level split for you.
This is another approach, not multidimensional:
parse_str(str_replace(array(':','/'), array('=','&'), $workers), $array);
print_r($array);
Shorter in PHP >= 5.4.0:
parse_str(str_replace([':','/'], ['=','&'], $workers), $array);
print_r($array);
yet another approach, since you didn't really give an example of what you mean by "bidimensional" ...
$workers="name1:age1/name2:age2/name3:age3";
parse_str(rtrim(preg_replace('~name(\d+):([^/]+)/?~','name[$1]=$2&',$workers),'&'),$names);
output:
Array
(
[name] => Array
(
[1] => age1
[2] => age2
[3] => age3
)
)
WP outputs an array:
$therapie = get_post_meta($post->ID, 'Therapieen', false);
print_r($therapie);
//the output of print_r
Array ( [0] => Massagetherapie )
Array ( [0] => Hot stone )
Array ( [0] => Massagetherapie )
How would I merge these arrays to one and delete all the exact double names?
Resulting in something like this:
theArray
(
[0] => Massagetherapie
[1] => Hot stone
)
[SOLVED] the problem was if you do this in a while loop it wont work here my solution, ty for all reply's and good code.: Its run the loop and pushes every outcome in a array.
<?php query_posts('post_type=therapeut');
$therapeAr = array(); ?>
<?php while (have_posts()) : the_post(); ?>
<?php $therapie = get_post_meta($post->ID, 'Therapieen', true);
if (strpos($therapie,',') !== false) { //check for , if so make array
$arr = explode(',', $therapie);
array_push($therapeAr, $arr);
} else {
array_push($therapeAr, $therapie);
} ?>
<?php endwhile; ?>
<?php
function array_values_recursive($ary) { //2 to 1 dim array
$lst = array();
foreach( array_keys($ary) as $k ) {
$v = $ary[$k];
if (is_scalar($v)) {
$lst[] = $v;
} elseif (is_array($v)) {
$lst = array_merge($lst,array_values_recursive($v));
}}
return $lst;
}
function trim_value(&$value) //trims whitespace begin&end array
{
$value = trim($value);
}
$therapeAr = array_values_recursive($therapeAr);
array_walk($therapeAr, 'trim_value');
$therapeAr = array_unique($therapeAr);
foreach($therapeAr as $thera) {
echo '<li><input type="checkbox" value="'.$thera.'">'.$thera.'</input></li>';
} ?>
The following should do the trick.
$flattened = array_unique(call_user_func_array('array_merge', $therapie));
or the more efficient alternative (thanks to erisco's comment):
$flattened = array_keys(array_flip(
call_user_func_array('array_merge', $therapie)
));
If $therapie's keys are strings you can drop array_unique.
Alternatively, if you want to avoid call_user_func_array, you can look into the various different ways of flattening a multi-dimensional array. Here are a few (one, two) good questions already on SO detailing several different methods on doing so.
I should also note that this will only work if $therapie is only ever a 2 dimensional array unless you don't want to flatten it completely. If $therapie is more than 2 dimensions and you want to flatten it into 1 dimension, take a look at the questions I linked above.
Relevant doc entries:
array_flip
array_keys
array_merge
array_unique
call_user_func_array
It sounds like the keys of the arrays you are generating are insignificant. If that's the case, you can do a simple merge then determine the unique ones with built in PHP functions:
$array = array_merge($array1, $array2, $array3);
$unique = array_unique($array);
edit: an example:
// Emulate the result of your get_post_meta() call.
$therapie = array(
array('Massagetherapie'),
array('Hot stone'),
array('Massagetherapie'),
);
$array = array();
foreach($therapie as $thera) {
$array = array_merge($array, $thera);
}
$unique = array_unique($array);
print_r($unique);
PHP's array_unique() will remove duplicate values from an array.
$tester = array();
foreach($therapie as $thera) {
array_push($tester, $thera);
}
$result = array_unique($tester);
print_r($result);