Split array to create an associative array - php

I have an array that looks like this:
a 12 34
b 12345
c 123456
So the array looks like
$array[0] = "a 12 34"
$array[1] = "b 12345"
$array[2] = "c 123456"
I am trying to create an associative array such that
[a] => 12 34
[b] => 12345
[c] => 123456
Can I possibly split the array into two, one for containing "a, b, c" and another for their contents and use the array_combine()? Or are there any other ways?

You can do that within a loop like the snippet below demonstrates. Quick-Test here:
$array = array("a 12 34", "b 12345", "c 123456");
$array2 = array();
foreach($array as $data){
preg_match("#([a-z])(\s)(.*)#i", $data, $matches);
list(, $key, $space, $value) = $matches;
$array2[$key] = $value;
}
var_dump($array2);
// YIELDS::
array(3) {
["a"]=> string(5) "12 34"
["b"]=> string(5) "12345"
["c"]=> string(6) "123456"
}
Or using a Blend of array_walk() and array_combine() which can be Quick-Tested Here.
<?php
$array = array("a 12 34", "b 12345", "c 123456");
$keys = array();
array_walk($array, function(&$data, $key) use (&$keys){
$keys[] = trim(preg_replace('#(\s.*)#i', '', $data));;
$data = trim(preg_replace('#(^[a-z])#i', '', $data));
});
$array = array_combine($keys, $array);
var_dump($array);;
// YIELDS::
array(3) {
["a"]=> string(5) "12 34"
["b"]=> string(5) "12345"
["c"]=> string(6) "123456"
}

You can do it without any difficulty :) A simple loop is possible to do it.
Create new array
Lopp on each row
Split each data (explode(' ', $row, 2), strstr, substr, ...) ?
Put data on your new array $array[$key] = $value;

You could use a combination of array_map, array_column and array_combine:
$array = array_map(function ($v) { return explode(' ', $v, 2); }, $array);
$array = array_combine(array_column($array, 0), array_column($array, 1));

Related

Sort array of hyperlinks by inner HTML

I have an array that is like this:
array(6) { [0]=> string(116) "A" [1]=> string(112) "C" [2]=> string(110) "B" [3]=> string(115) "F" [4]=> string(113) "D" [5]=> string(112) "E" }
and which letter represents an Hyperlink, so each letter is:
Letter
I want to sort this array so I have it sorted by its letter/innerHTML
I want to sort this before echoing.
Any help will be appreciated.
Thank you
You can split the links and create new associative array using letter as key and full link as value. Try below code.
$links=['D','B','C','A'];
$new_links=[];
foreach($links as $link){
$array_1= explode(">",$link);
$array_2 = explode("<",$array_1[1]);
$new_links[$array_2[0]]=$link;
}
ksort($new_links);
You can usort with a callback that compares just the link text.
$link = '/.+>(.+)<.+/';
usort($array, function($a, $b) use ($link) {
return preg_replace($link, '\1', $a) <=> preg_replace($link, '\1', $b);
// If you're on PHP 5 without the <=> operator, you can use strcmp instead
// return strcmp(preg_replace($link, '\1', $a), preg_replace($link, '\1', $b));
});
I'm not a regex expert, so there's probably a better way to write the pattern, but the general idea is the same regardless. It's common knowledge that it's not a good idea to parse arbitrary HTML with regex, but for something like an array of <a> tags it seems pretty har̴ml҉es͝s.
I would suggest using strip_tags() and sorting the result although if you want to preserve multiple link instances you need to use a multidimensional array and sort that:
$unsortedArray = [
'Orange',
'Banana',
'Apple',
'pineapple',
'Banana',
'Apple 2',
];
$sortedArray = [];
function sortLinks($links) {
$splitArray = [];
$sortedArray = [];
foreach($links as $link) {
$label = strip_tags($link);
$splitArray[] = ['link' => $link, 'label' => $label];
}
usort($splitArray, function ($a, $b) {
return $a['label'] <=> $b['label'];
});
foreach ($splitArray as $item) {
$sortedArray[] = $item['link'];
}
return $sortedArray;
}
$sorted = sortLinks($unsortedArray);
echo '<pre>' . print_r($sorted, 1) . '</pre>';
The output should be:
Array
(
[0] => Apple
[1] => Apple 2
[2] => Banana
[3] => Banana
[4] => Orange
[5] => pineapple
)

PHP combine key value array and regular array

I have 2 arrays:
array1 :
[0]=>
string(10) "AAAAAAAAAAA"
[1]=>
string(10) "BBBBBBBBBBB"
...
and array2:
[0]=>
float(0)
[550]=>
float(55)
...
I need a result like this:
"AAAAAAAAAAA" : 0 : 0
"BBBBBBBBBBB" : 550: 55
...
i.e. how to combine the arrays. How do i get that?
suppose you two arrays have the same length,
$keys = array_keys($array1);
$values = [];
foreach($array2 as $k=>$v)
{
$values[] = $k.':'.$v;
}
$result = array_combine($keys, $values);
The result you want is not clear... if each rows are just a string, this should work :
$a = [
0 => "AAAAAAAAAAA",
1 => "BBBBBBBBBBB"
];
$b = [
0 => (float) 0,
550 => (float) 55
];
$result = array_map(
function($v1, $v2, $v3) {
return "$v1 : $v2 : $v3";
},
$a, array_keys($b), $b
);
var_dump($result);

Reset array keys in multidimensional array, recursive, by reference

I want to reset keys in a big, multidimensional array. I already found a solution which is actually work:
$fix_keys = function(array $array) use (&$fix_keys)
{
foreach($array as $k => $val)
{
if (is_array($val))
{
$array[$k] = $fix_keys($val);
}
}
return array_values($array);
};
and the problem is, if I pass big arrays to it, it becomes slow and memory consuming. What about refactoring with working references:
$fix_keys = function(array &$array) use (&$fix_keys)
{
foreach($array as $k => &$val)
{
if (is_array($val))
{
$array[$k] = $fix_keys($val);
}
}
unset($val);
$array = array_values($array);
};
but it messed up the array, all I get is [0] => null. What is wrong?
Edit: so input data:
$a = [
'a' => 1,
'b' => 2,
'c' => [
'aa' => 11,
'bb' => [
'ccc' => 1
],
'cc' => 33
]
];
and I want to have:
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
array(3) {
[0]=>
int(11)
[1]=>
array(1) {
[0]=>
int(1)
}
[2]=>
int(33)
}
}
If memory is an issue you can try using yield. I'm not sure if this fits your needs, but here it is:
function reduce($array){
foreach($array as $key => $value){
if(is_array($value)){
reduce($value);
}
}
yield array_values($array);
}
You can also use send if you need to apply some logic to the generator.
I found the solution:
$fix_keys = function(array &$array) use (&$fix_keys)
{
foreach(array_keys($array) as $k)
{
if (is_array($array[$k]))
{
$fix_keys($array[$k]);
}
}
$array = array_values($array);
};

How to merge two arrays by its values in PHP?

What I need is really simple:
I have two arrays like that:
<?php
$a1 = [1,2,3];
$a2 = [2,3,4];
I need to combine them so that the result is:
$result = [1,2,3,4];
I've tried array_merge but the result was [1,2,3,2,3,4]
You can find an answer to this here: Set Theory Union of arrays in PHP
By expanding on your current method. You can call array_unique and sort on the resulting array.
$a = [1,2,3];
$b = [2,3,4];
$result = array_merge($a, $b);
$result = array_unique($result);
sort($result);
This will result in:
array(4) {
[0] = int(1) 1
[1] = int(1) 2
[2] = int(1) 3
[3] = int(1) 4
}
function merges(/*...*/){
$args=func_get_args();
$ret=array();
foreach($args as $arg){
foreach($arg as $key=>$v)
{
$ret[$key]=$v;
}
}
return $ret;
}
untested, but i guess this would work.. will delete all duplicate keys and return the last key/value pair it found of duplicates
This might be what you are looking for
$result = $a1 + $a2 //union operation
reference
Array Operations
Example
$a = array("a" => "apple", "b" => "banana");
$b = array("a" => "pear", "b" => "strawberry", "c" => "cherry");
$c = $a + $b; // Union of $a and $b
echo "Union of \$a and \$b: \n";
var_dump($c);
Ouput
Union of $a and $b:
array(3) {
["a"]=>
string(5) "apple"
["b"]=>
string(6) "banana"
["c"]=>
string(6) "cherry"
}

regular expression to split formatted string into associative array

I have a string that looks like:
KEY1,"Value"KEY2,"Value"Key3,"Value"
This string will always vary in the number of keys/values i need an associative array:
array (
'KEY1' => 'Value',
'KEY2' => 'Value',
'KEY3' => 'Value'
);
of the data contained in the string, a regular expression would be best I suppose?
Assuming your values don't contain a " in them you can do:
$str = 'KEY1,"Value1"KEY2,"Value2"Key3,"Value3"';
$pieces = preg_split('/(?<=[^,]")/',$str,-1,PREG_SPLIT_NO_EMPTY);
$result = array();
foreach($pieces as $piece) {
list($k,$v) = explode(",",trim$piece);
$result[$k] = trim($v,'"');
}
See it in action!
php> $str = 'KEY1,"Value"KEY2,"Value"Key3,"Value"';
php> $hash = array();
php> preg_match_all("/(.*?),\"(.*?)\"/", $str, $m);
php> foreach($m[1] as $index => $key) {
... $hash[$key] = $m[2][$index];
... }
php> var_dump($hash);
array(3) {
["KEY1"]=>
string(5) "Value"
["KEY2"]=>
string(5) "Value"
["Key3"]=>
string(5) "Value"
}
If the key changes between values then you'll need preg_split(). If the key is always the same then explode() should be more than adequate.

Categories