from one-dimensional to two-dimensional array - php

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 --

Related

Move last array string to end of second last array string

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',
)

Randomly select words from multi-dimension array

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);

PHP: take out duplicate digits from an array then print them out

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);

Convert CSV string to Array keys and a value of 1 or true

Please could someone help find a better solution to the code below.
Here is my existing solution:
$list = '54,78,3,5';
$list = explode(",",$list);
foreach($list as $k => $v) { $compare[$v] = 1; }
when i run array_flip instead of the foreach on $list it returns an array like this:
Array(
54 => 0,
78 => 1,
...
)
I need this so another array which is already in this format can be compared with an IF statment:
Array(
54 => 1,
78 => 1,
...
)
$list = '54,78,3,5';
$list = explode(",",$list);
$array = array_combine($list, array_fill(0, count($list), 1));
print_r($array);
Array
(
[54] => 1
[78] => 1
[3] => 1
[5] => 1
)
array_fill() will create an array with all of its values being the number 1 at the same size as the $list array. array_combine() then creates a new array with the values of $list as the keys and the values created by array_fill();
Demo
Do you need the original $list to be a variable? Can't you just make it an array from the start wherever the data comes from, and append 1 or true to the value?
Otherwise, before your current foreach, add a new loop and go through $list (which you made into an array) and make a new array appending the required value to each key (keys taken from $list):
foreach ($list as $key)
{
$new_array[$key] = 1;
}

How to remove prefix in array keys

I try to remove a prefix in array keys and every attempt is failing. What I want to achieve is to:
Having: Array ( [attr_Size] => 3 [attr_Colour] => 7 )
To Get: Array ( [Size] => 3 [Colour] => 7 )
Your help will be much appreciated...
One of the ways To Get:Array ( [Size] => 3 [Colour] => 7 ) From your Having: Array ( [attr_Size] => 3 [attr_Colour] => 7 )
$new_arr = array();
foreach($Your_arr as $key => $value) {
list($dummy, $newkey) = explode('_', $key);
$new_arr[$newkey] = $value;
}
If you think there'll be multiple underscores in keys just replace first line inside foreach with list($dummy, $newkey) = explode('attr_', $key);
If I understood your question, you don't have to use implode() to get what you want.
define(PREFIX, 'attr_');
$array = array('attr_Size' => 3, 'attr_Colour' => 7);
$prefixLength = strlen(PREFIX);
foreach($array as $key => $value)
{
if (substr($key, 0, $prefixLength) === PREFIX)
{
$newKey = substr($key, $prefixLength);
$array[$newKey] = $value;
unset($array[$key]);
}
}
print_r($array); // shows: Array ( [Size] => 3 [Colour] => 7 )
Because the first character that you'd like to retain in each key starts with an uppercase letter, you can simply left-trim lowercase letters and underscores and voila. To create a "mask" of all lowercase letters and the underscore, you could use a..z_, but because attr_ is the known prefix, _art will do. My snippet, admittedly, is narrowly suited to the asker's sample data, does not call explode() to create a temporary array, and does not make multiple function calls per iteration. Use contentiously.
Code: (Demo)
$array = [
'attr_Size' => 3,
'attr_Colour' => 7
];
$result = [];
foreach ($array as $key => $value) {
$result[ltrim($key, '_art')] = $value;
}
var_export($result);
Output:
array (
'Size' => 3,
'Colour' => 7,
)

Categories