I have an array like this:
$array = array(
0 => "a,b",
1 => "c,d",
2 => "e,f",
3 => "g,h",
);
I would like to merge the last two array elements (2 and 3) into a one like this:
$array = array(
0 => "a,b",
1 => "c,d",
2 => "e,f,g,h",
);
How can I do it using PHP?
Remove tow last items by array_splice and add implode of them
$temp = array_splice($array,-2);
$result = array_merge($array, (array) implode(',', $temp));
demo
As #Nick mentioned, you can do it by
$temp = array_splice($array,-2);
$array[] = implode(',', $temp);
Simple, use array_pop() to remove the last 2 elements, then concatenate them, then add them back to the original array.
$array = array(
0 => "a,b",
1 => "c,d",
2 => "e,f",
3 => "g,h",
);
$element3 = array_pop($array); //grab value of the last element, and remove it from the array.
$element2 = array_pop($array);
$array[] = "$element2,$element3";
this will always work if it's always supposed to be the last 2 elements.
This can be achieved with a one-liner that unconditionally pushes that joined strings of the last two elements after consuming them with array_splice(). In other words, the last two elements are removed, joined, then re-pushed into the array as a single element.
The $temp variable in #solash58's answer is not necessary -- the consumption of the last two elements will occur before the auto-incremented index is generated.
Code: (Demo)
$array = [
0 => "a,b",
1 => "c,d",
2 => "e,f",
3 => "g,h",
];
$array[] = implode(",", array_splice($array, -2));
var_export($array);
Output:
array (
0 => 'a,b',
1 => 'c,d',
2 => 'e,f,g,h',
)
Related
I have a multi-dimensional array and from where i want to choose 11 different words. Each word from different array index.
Here is the array link: My multi-dimensional array
array (
'w' =>
array (
0 => 'walls',
1 => 'well',
2 => 'why',
),
'e' =>
array (
0 => 'end',
),
'a' =>
array (
0 => 'advantage',
1 => 'afford',
2 => 'affronting',
3 => 'again',
4 => 'agreeable',
5 => 'ask',
6 => 'at',
),
'c' =>
array (
0 => 'children',
1 => 'civil',
2 => 'continual',
)
);
My Desire Output:
From w => well
From e => end
From a => again
and so on.
Output like: array(well, end, again, ...) as array.
Use the following code:
$f = array_keys($result); // grouping the indices, namely, the characters
$a = "";
for($c=0;$c<count($f);$c++){
$a .= $f[$c];
} // grouping the indices stored in array $f to a string, $a
$words = array();
for($c=0;$c<11;$c++){
$random = $a[rand(0,strlen($a)-1)];
$k = $result[$random];
// $k stores the array of the character index, stored in $result
$random2 = rand(0,count($k)-1);
$words[$c] = $k[$random2];
// choose a word from a given character array
$a = preg_replace("/".$random."/","",$a);
// remove the character from $a to prevent picking words which start with the same character
}
print_r($words);
I've tested and it was proved working
https://3v4l.org/qi1VP
You can achieve this usin array_rand() function :
PHP
$words = [];
$limit = 3; //Replace this with your limit, 11
$count = 0;
shuffle($array);
foreach($array as $key => $value) {
$words[] = $value[array_rand($value)];
$count++;
if ($limit == $count) {
break;
}
}
EvalIn
Check Online, and let me know.
using shuffle and array_slice you can get what you want.
A shuffle function makes your array random, and array slice slice 11 sub array from it.
Array slice takes 3 argument, first one is the array, second one is the offset from where you want to start and last one how much you need to cut.
$words = array();
shuffle($result);
$res = array_slice($result, 0, 11);
foreach($res as $key => $value){
shuffle($value);
$words[] = $value[0];
}
print_r($words);
I'm probably [super]overthinking this. I'm trying to analyze an array with values like [1,9], [4,6] [5,5], [6,4], [9,1] and duplicate digits (I'm having a super brain fart and can't even remember the term for numbers like this) remove (the last two) so that only [1,9], [4,6] [5,5] are printed.
I was thinking that turning this array into a string and using preg_match, but I'm pretty sure this wouldn't work even if I had the correct regex.
If you have an array of pairs like this:
$x = array(
array(1,9),
array(4,6),
array(5,5),
array(6,4),
array(9,1)
);
Here is one way to get the unique pairs:
foreach ($x as $pair) {
sort($pair);
$unique_pairs[implode(',', $pair)] = $pair;
}
This uses string representations of each sorted pair as keys in a new array, so the result will have distinct values by definition.
As far as the printing them out part of your question, once you have the unique values you can loop over them and print them out in whichever format you like, for example:
foreach ($unique_pairs as $pair) { vprintf("[%d,%d]<br>", $pair); }
It looks like elements are distributed symmetrically.
We can cut the array in two halves and get only the first half with array_slice():
$array = array(
array(1,9),
array(4,6),
array(5,5),
array(6,4),
array(9,1),
);
print_r(array_slice($array, 0, ceil(count($array) / 2)));
Result:
Array(
[0] => Array(
[0] => 1
[1] => 9
)
[1] => Array(
[0] => 4
[1] => 6
)
[2] => Array(
[0] => 5
[1] => 5
)
)
Demo at Codepad.
ceil() is used to round the number up to the next highest integer if there is an even number of items in the array. Example: if there is 3 items in the array, 5 / 2 will return 2.5, we want 3 items so we use ceil(2.5) which gives 3.
Example with 3 items:
$array = array(
array(1,9),
array(5,5),
array(9,1),
);
print_r(array_slice($array, 0, ceil(count($array) / 2)));
Result:
Array(
[0] => Array(
[0] => 1
[1] => 9
)
[1] => Array(
[0] => 5
[1] => 5
)
)
Example with 4 items:
$array = array(
array(1,9),
array(7,7),
array(7,7),
array(9,1),
);
print_r(array_slice($array, 0, ceil(count($array) / 2)));
Result:
Array(
[0] => Array(
[0] => 1
[1] => 9
)
[1] => Array(
[0] => 7
[1] => 7
)
)
If I'm correct in understanding what you are trying to do, you want to remove the final 2 elements from the array?
There is a function in PHP called array_pop that removes the final element from the array.
$array = array_pop($array);
So if you run this twice, you will remove the final 2 elements from the array.
This is how I'd do it (and I hope I am not overthinking this :))
$stringArray = array();
$stringArray[] = '1,9';
$stringArray[] = '4,6';
$stringArray[] = '5,5';
$stringArray[] = '6,4';
$stringArray[] = '9,1';
foreach($stringArray as &$numString) {
$numString = explode(',', $numString);
usort($numString, function($a, $b) {return $a - $b;});
$numString = implode(',', $numString);
}
$a = array_unique($a);
print_r($a);
You basically explode every element into a subarray, sort it and then implode it back. After calling the array_unique, you're left with unique values in the array.
The output would be
Array
(
[0] => 1,9
[1] => 4,6
[2] => 5,5
)
The result you suggest treats [a,b] as equivalent to [b,a] which makes the problem a lot more complex. The code below gives the result you asked for, but without really understanding what the problem is that you are trying to fix and whether [1,9] is equivalent to [9,1] in the solution:
$a=array(array(1,9),array(4,6),...
$dup=array();
for ($i=0; $i<count($a) -1; $i++) {
for ($j=$i+1; $j<count($a); $j++) {
if (($a[$i][0]==$a[$j[0] && $a[$i][1]==$a[$j[1])
|| ($a[$i][0]==$a[$j[1] && $a[$i][1]==$a[$j[0])) {
$dup[]=$j;
}
}
}
foreach ($dup as $i) {
unset($a[$i]);
}
So I'm actually going to assume your question to have a different meaning than everyone else did. I believe what you're asking is:
How do you filter out array items where a reverse of the item has already been used?
<?php
// The example set you gave
$numberSets = [[1, 9], [4, 6], [5, 5], [6, 4], [9, 1]];
// Initialize an empty array to keep track of what we've seen
$keys = [];
// We use array filter to get rid of items we don't want
// (Notice that we use & on $keys, so that we can update the variable in the global scope)
$numberSets = array_filter($numberSets, function($set) use(&$keys) {
// Reverse the array
$set = array_reverse($set);
// Create a string of the items
$key = implode('', $set);
// Get the reverse of the numbers
$reversedKey = strrev($key);
// If the palindrome of our string was used, return false to filter
if (isset($keys[$reversedKey])) {
return false;
}
// Set the key so it's not used again
// Since $keys is being passed by reference it is updated in global scope
$keys[$key] = true;
// Return true to NOT filter this item, since it or it's reverse were not matched
return true;
});
var_dump($numberSets);
I have array like and used array_keys to get keys:
$arr = array( 1 => 1,
2 => 3,
3 => 2,
5 => 0,
6 => 0 );
$new_arr = array_keys($arr);
Now, I want to get array_keys if value is not zero. How can i do this?
Please help.
Run array_filter on your array before you get the keys; that removes the 0 values and you only get the keys you need.
$new_arr = array_keys(array_filter($arr));
Output
Array
(
[0] => 1
[1] => 2
[2] => 3
)
You can remove all elements with values before passing array for array_keys:
NULL
null
''
0
With the following:
array_filter($array, function($var) {
// Remove all empty values defined in the above list.
return !is_empty($var);
});
$num_array = array(1,2,3,4,0,0);
$zero_val = array_keys($num_array,!0);
print_r($zero_val);
I have the following array:
$list = array('item1','item2','item3','item4','item5','item6');
i need to take this array and break it into smaller arrays within 1 array for the csv. Each small array needs to have '999999' at index 0, followed by the next two items in the $list array. So the final result would be like this:
$newList = array(
array(999999, "item1" , "item2"),
array(999999, "item3" , "item4"),
array(999999, "item5" , "item6")
);
The original list array may contain up to 100 values at sometimes. What is the best way to achieve this?
Here's a different way of doing it, please see the comment as to where you place your additional elements to be prepended (you could add a second array into the merge at the end to add elements after the 2 list items too!)
See here for working example: http://codepad.org/hucpT5Yo
<?php
$list = array('item1','item2','item3','item4','item5','item6');
$list_chunks = array_chunk($list,2);
$list_chunks2 = array_map(
create_function(
'$x',
'return array_merge(array(
/* This array is prepended to the second,
add as many elements as you like */
999999,
"another element to add",
483274832
),
$x);'),
$list_chunks);
print_r($list_chunks2);
?>
$idx = 0;
$newarray = array();
$temparray = array('999999');
foreach($oldarray as $value) {
$temparray[] = $value;
if ((++$idx % 2)) == 0) {
$newarray[] = $temparray;
$temparray = array('999999');
}
}
Break your flat array into an array 2-element rows with array_chunk(), then call array_merge() on each row with the static value 999999 nested in an array and nominated as the first argument.
The modern syntax for the chunk-n-merge technique demonstrated by #Lee looks like this:
Code: (Demo)
$list = ['item1','item2','item3','item4','item5','item6'];
var_export(
array_map(fn($row) => array_merge([999999], $row), array_chunk($list, 2))
);
Output:
array (
0 =>
array (
0 => 999999,
1 => 'item1',
2 => 'item2',
),
1 =>
array (
0 => 999999,
1 => 'item3',
2 => 'item4',
),
2 =>
array (
0 => 999999,
1 => 'item5',
2 => 'item6',
),
)
I have this PHP one dimensional array:
Array
(
[Female--N] => 11
[Male--N] => 11
[Humans--N] => 11
[Adult--N] => 8
[Adolescent--N] => 8
[Reaction Time-physiology--N] => 6
[Acoustic Stimulation-methods--N] => 6
[Schizophrenia-genetics--Y] => 5
[Motion Perception--N] => 3
)
And i want a new array from this that looks like (i think this tow-dimensional..?):
Array
(
[Female][N] => 11
[Male][N] => 11
[Humans][N] => 11
[Adult][N] => 8
[Adolescent][N] => 8
[Reaction Time-physiology][N] => 6
[Acoustic Stimulation-methods][N] => 6
[Schizophrenia-genetics][Y] => 5
[Motion Perception][N] => 3
)
Can i use split method on key elements?
Little bit harder... i also need to split on the single '_' underscore, i did this to prevent the columns getting mixed up... But the example below doesn't do the job right...
$new_array = array();
foreach($MeshtagsArray as $key => $value) {
$parts = explode('__', $key, 2);
$parts2 = explode('_', $key, 2);
$new_array[] = array(
'discriptor' => $parts[0],
'qualifier' => $parts2[1],
'major' => $parts[1],
'#occurence' => $value
);
So the output should be something like:
[0] => Array
(
[discriptor] => Female
[qualifier] =>
[major] => N
[#occurence] => 11
........
[5] => Array
(
[discriptor] => Reaction Time
[qualifier] => physiology
[major] => N
[#occurence] => 6
Best regards,
Thijs
UPDATED
$new_array = array();
foreach($old_array as $key => $value) {
$parts1 = explode('--', $key, 2);
$parts2 = explode('-', $parts1[0], 2);
$new_array[] = array(
'descriptor' => $parts2[0],
'qualifier' => count($parts2) > 1 ? $parts2[1] : '',
'major' => $parts1[1],
'#occurence' => $value
);
}
$new_array will now be a numerically indexed, multidimensional array. Each top level key will contain an associative array of the elements you require.
In the future, feel free to explain the entire problem from the beginning, that way we can all better help you!
Explanation
According to php.net:
array explode ( string $delimiter , string $string [, int $limit ] )
Returns an array of strings, each of which is a substring of string formed by splitting it on boundaries formed by the string delimiter.
The array in your problem is associative; it's keys are strings. This makes it is a simple matter to iterate over the array with foreach and explode the keys into parts. I use a limit parameter to ensure that there will be no more than two parts.
Also, since one delimiter is a doubled version of the other, we have to first explode on the double -- delimiter, and then explode on the single - delimiter.
Technically, we could have used a single explode—with no limit parameter—and the single - delimiter. Then we could have inferred which element part belonged where. However, sometimes there is no qualifier. To get around this problem, I've used two explodes, and a ternary operator that counts the returned number of elements from the second explode.
Try this function:
function convertArray($array)
{
$return = array();
foreach ($array as $key=>$value)
{
$exploded = explode('--', $key);
$return[$exploded[0]][$exploded[1]] = $value;
}
return $return;
}
Assuming you are splitting on -- and you want a two dimensional array, try the following.
foreach ($the_array as $key => $value) {
// split key into new indexes
$indexes = explode('--', $key);
if (count($indexes) == 2) {
// create new dimension and set value
$the_array[$indexes[0]][$indexes[1]] = $value;
// remove old index
unset($the_array[$key]);
}
}
Note: This converts on the original array and ensures the key contains --