getting a unique values from array - php

I currently have an array that looks like the one below but I only want to display show results in the array from which are unique (description), I presume with array_unique? but I keep getting the same results?
Here is my array:
$taglist = array(5) {
[0]=> array(5) {
["id"]=> string(2) "27"
["page_id"]=> string(2) "18"
["description"]=> string(10) "Web Design"
["slug"]=> string(10) "web-design"
["visibility"]=> string(7) "visible"
}
[1]=> array(5) {
["id"]=> string(2) "29"
["page_id"]=> string(2) "18"
["description"]=> string(3) "Tutorials"
["slug"]=> string(3) "tutorials"
["visibility"]=> string(7) "visible"
}
[2]=> array(5) {
["id"]=> string(2) "31"
["page_id"]=> string(2) "21"
["description"]=> string(3) "tag"
["slug"]=> string(3) "tag"
["visibility"]=> string(7) "visible"
}
[3]=> array(5) {
["id"]=> string(2) "32"
["page_id"]=> string(2) "21"
["description"]=> string(10) "Web Design"
["slug"]=> string(10) "web-design"
["visibility"]=> string(7) "visible"
}
}
Here is my while:
$items = array();
$results = $taglist;
foreach ($results as $result)
{
$items[]= $result['description'];
$items = array_unique($items);
}
echo '<ul>';
while ($tag_item = current($items))
{
echo '<li>'.$tag_item['description'].'</li>';
next($items);
}
echo '</ul>';

$taglist = array(
0 => array('description'=>'one'),
1 => array('description'=>'two'),
2 => array('description'=>'one'),
3 => array('description'=>'three'),
4 => array('description'=>'one'),
);
// echo var_export($taglist, 1); // uncomment to see the diff vs var_dump()
foreach($taglist as $tag){
$new[] = $tag['description'];
}
var_dump(array_unique($new));

Related

PHP Convert multidimensional array key to be array multidimensional value

I have problem formatting array to become fancytree format, below array output from db:
array(44) {
[0]=>
array(3) {
["id"]=>
string(2) "35"
["title"]=>
string(28) "ROOT1"
["path"]=>
string(28) "ROOT1"
}
[1]=>
array(3) {
["id"]=>
string(2) "36"
["title"]=>
string(27) "SUB_A"
["path"]=>
string(56) "ROOT1>SUB_A"
}
[2]=>
array(3) {
["id"]=>
string(2) "39"
["title"]=>
string(12) "SUB_A_1"
["path"]=>
string(69) "ROOT1>SUB_A>SUB_A_1"
}
[3]=>
array(3) {
["id"]=>
string(2) "37"
["title"]=>
string(28) "SUB_A_2"
["path"]=>
string(85) "ROOT1>SUB_A>SUB_A_2"
}
[4]=>
array(3) {
["id"]=>
string(2) "40"
["title"]=>
string(30) "SUB_A_3"
["path"]=>
string(87) "ROOT1>SUB_A>SUB_A_3"
}
[5]=>
array(3) {
["id"]=>
string(2) "43"
["title"]=>
string(19) "SUB_A_4"
["path"]=>
string(76) "ROOT1>SUB_A>SUB_A_4"
}
[6]=>
array(3) {
["id"]=>
string(2) "41"
["title"]=>
string(12) "SUB_A_5"
["path"]=>
string(69) "ROOT1>SUB_A>SUB_A_5"
}
[7]=>
array(3) {
["id"]=>
string(1) "1"
["title"]=>
string(20) "ROOT2"
["path"]=>
string(20) "ROOT2"
}
[8]=>
array(3) {
["id"]=>
string(2) "30"
["title"]=>
string(37) "ROOT3"
["path"]=>
string(37) "ROOT3"
}
[9]=>
array(3) {
["id"]=>
string(2) "34"
["title"]=>
string(21) "SUB_B"
["path"]=>
string(59) "ROOT3>SUB_B"
}
[10]=>
array(3) {
["id"]=>
string(2) "31"
["title"]=>
string(15) "SUB_C"
["path"]=>
string(53) "ROOT3>SUB_C"
}
I want to format values of path become structured array, here is what I try:
function format(array $data) : array
{
$single = [];
// format to single data
foreach ($data as $value) {
$single[] = $value['path'];
}
$result = [];
foreach ($single as $path) {
$parts = explode('>', $path);
$section = &$result;
$sectionName = '';
foreach ($parts as $part) {
$sectionName = $part;
if (array_key_exists($sectionName, $section) === FALSE) {
$section[$sectionName] = [];
}
$section = &$section[$sectionName];
}
}
return $result;
}
result:
array(3) {
["ROOT1"]=>
array(1) {
["SUB_A"]=>
array(5) {
["SUB_A_1"]=>
array(0) {
}
["SUB_A_2"]=>
array(0) {
}
["SUB_A_3"]=>
array(0) {
}
["SUB_A_4"]=>
array(0) {
}
["SUB_A_5"]=>
array(0) {
}
}
}
["ROOT2"]=>
array(0) {
}
["ROOT3"]=>
array(2) {
["SUB_B"]=>
array(0) {
}
["SUB_C"]=>
array(0) {
}
}
i need to include values of id and title to each path as expected result:
array(3) {
[0]=>
array(3) {
["title"]=>
string(5) "ROOT1"
["id"]=>
int(35)
["children"]=>
array(1) {
[0]=>
array(3) {
["title"]=>
string(5) "SUB_A"
["id"]=>
int(36)
["children"]=>
array(5) {
[0]=>
array(2) {
["title"]=>
string(7) "SUB_A_1"
["id"]=>
int(39)
}
[1]=>
array(2) {
["title"]=>
string(7) "SUB_A_2"
["id"]=>
int(37)
}
[2]=>
array(2) {
["title"]=>
string(7) "SUB_A_3"
["id"]=>
int(40)
}
[3]=>
array(2) {
["title"]=>
string(7) "SUB_A_4"
["id"]=>
int(43)
}
[4]=>
array(2) {
["title"]=>
string(7) "SUB_A_5"
["id"]=>
int(41)
}
}
}
}
}
[1]=>
array(2) {
["title"]=>
string(5) "ROOT2"
["id"]=>
int(1)
}
[2]=>
array(3) {
["title"]=>
string(5) "ROOT3"
["id"]=>
int(30)
["children"]=>
array(2) {
[0]=>
array(2) {
["title"]=>
string(5) "SUB_B"
["id"]=>
int(34)
}
[1]=>
array(2) {
["title"]=>
string(5) "SUB_C"
["id"]=>
int(31)
}
}
}
}
I would be grateful for any help you are able to provide.
Here's how I would do it. Test
I used arrow functions to reduce the amount of lines and there are inline comments to explain what I did.
<?php
$data = [["id"=> "35", "title"=> "ROOT1", "path"=> "ROOT1"], ["id"=> "36", "title"=> "SUB_A", "path"=> "ROOT1>SUB_A"], ["id"=> "37", "title"=> "SUB_A_1", "path"=> "ROOT1>SUB_A>SUB_A_1"], ["id"=> "38", "title"=> "SUB_A_2", "path"=> "ROOT1>SUB_A>SUB_A_2"], ["id"=> "39", "title"=> "SUB_A_3", "path"=> "ROOT1>SUB_A>SUB_A_3"], ["id"=> "40", "title"=> "SUB_A_4", "path"=> "ROOT1>SUB_A>SUB_A_4"], ["id"=> "41", "title"=> "SUB_A_5", "path"=> "ROOT1>SUB_A>SUB_A_5"], ["id"=> "1", "title"=> "ROOT2", "path"=> "ROOT2"], ["id"=> "30", "title"=> "ROOT3", "path"=> "ROOT3"], ["id"=> "34", "title"=> "SUB_B", "path"=> "ROOT3>SUB_B"], ["id"=> "31", "title"=> "SUB_C", "path"=> "ROOT3>SUB_C"]];
// The path is defaulted to an empty string, so the regex would return the highest level elements only because they don't have any `>`
function get_children($data, $path = '')
{
$results = array_values(array_filter($data, fn($item) => preg_match("/^{$path}[^>]+$/", $item['path'])));
// This regex, uses the passed path (e.g ROOT1) and searches for elements with anything but another `>`, because `>` signifies an inner directory.
// So this would return elements with a path like `ROOT1>SUB_A, ROOT1>SUB_B` but not `ROOT1>SUB_A>SUB_A_1`
foreach($results as $i => $result) {
// then I iterate through the result to get the element's children
$children = array_values(get_children($data, "{$result['path']}>"));
if (count($children)) $results[$i]['children'] = $children;
unset($results[$i]['path']); // Removing the path key from the array
}
return $results;
}
$format = fn($data) => get_children($data);
print_r($format($data));

PHP push new data into given array

I may seem having difficulty in understanding on how array works. So result, I can't work on the issue.
foreach($results as $key => $value){
$product_key = array(
'key' => $key
);
array_push($results, $product_key);
}
var_dump($results); exit;
Expected Output
array(2) {
[0]=>
object(stdClass)#21 (4) {
["items_id"]=>
string(1) "1"
["item_name"]=>
string(6) "laptop"
["price"]=>
string(5) "20000"
["quantity"]=>
string(2) "10"
["key"]=>
int(0)
}
[1]=>
object(stdClass)#22 (4) {
["items_id"]=>
string(1) "2"
["item_name"]=>
string(10) "smartphone"
["price"]=>
string(5) "10000"
["quantity"]=>
string(3) "200"
["key"]=>
int(1)
}
Unexpected Output
array(4) {
[0]=>
object(stdClass)#21 (4) {
["items_id"]=>
string(1) "1"
["item_name"]=>
string(6) "laptop"
["price"]=>
string(5) "20000"
["quantity"]=>
string(2) "10"
}
[1]=>
object(stdClass)#22 (4) {
["items_id"]=>
string(1) "2"
["item_name"]=>
string(10) "smartphone"
["price"]=>
string(5) "10000"
["quantity"]=>
string(3) "200"
}
[2]=>
array(1) {
["key"]=>
int(0)
}
[3]=>
array(1) {
["key"]=>
int(1)
}
}
You push new value (which is array) to the end of existsing array, what do you expect then?
If you want to modify current interated array value use this approach:
foreach($results as $key => $value) {
// use `->` as `$value` is object
$value->key = $key;
}
var_dump($results); exit;

unexpected changes - overriding object inside foreach php

I've got array of object form database like below:
array(3) {
[1]=>
array(2) {
[0]=>
object(stdClass)#99 (3) {
["id"]=>
string(2) "42"
["name"]=>
string(4) "NAME1"
["type"]=>
string(1) "6"
}
[1]=>
object(stdClass)#98 (3) {
["id"]=>
string(3) "146"
["name"]=>
string(3) "STH1"
["type"]=>
string(1) "2"
}
}
[2]=>
array(2) {
[0]=>
object(stdClass)#97 (3) {
["id"]=>
string(2) "422"
["name"]=>
string(4) "NAME2"
["type"]=>
string(1) "3"
}
[1]=>
object(stdClass)#96 (3) {
["id"]=>
string(3) "16"
["name"]=>
string(3) "STH2"
["type"]=>
string(1) "2"
}
}
[3]=>
array(2) {
[0]=>
object(stdClass)#95 (3) {
["id"]=>
string(2) "11"
["name"]=>
string(4) "NAME3"
["type"]=>
string(1) "5"
}
[1]=>
object(stdClass)#94 (3) {
["id"]=>
string(3) "69"
["name"]=>
string(3) "STH3"
["type"]=>
string(1) "3"
}
}
}
And if i want to add the same object to the next array and change value of its type, i override the current object. How can i fix it? My foreach loop below:
foreach($events as $key => $event){
foreach($event as $k => $v){
if($v->type == 6){
$v->type = "0";
$events[$key+1][] = $v;
$v->type = "6";
}
}
}
If my guess what you are trying to achieve is right i would go like this
foreach($events as $key => $event){
foreach($event as $k => $v){
if($v->type == 6){
$tmp = $v;
$tmp->type="0";
$events[$key+1][] = $tmp;
}
}
}

Sort multiple array with same order

Below is example of my array
["value"]=>
array(16) {
[0]=>
string(5) "4"
[1]=>
string(4) "2"
[2]=>
string(4) "1"
[3]=>
string(4) "3"
}
["id"]=>
array(16) {
[0]=>
string(4) "four-id"
[1]=>
string(4) "two-id"
[2]=>
string(4) "one-id"
[3]=>
string(4) "three-id"
}
Now I am sorrting using array_multisort($arr["value"],SORT_NUMERIC, SORT_DESC); , which results in below output.
["value"]=>
array(16) {
[0]=>
string(5) "4"
[1]=>
string(4) "3"
[2]=>
string(4) "2"
[3]=>
string(4) "1"
}
["id"]=>
array(16) {
[0]=>
string(4) "four-id"
[1]=>
string(4) "two-id"
[2]=>
string(4) "one-id"
[3]=>
string(4) "three-id"
}
I want $arr["id"] to be sorted based on same sorting order of $arr["value"] like below
["id"]=>
array(16) {
[0]=>
string(4) "four-id"
[1]=>
string(4) "three-id"
[2]=>
string(4) "two-id"
[3]=>
string(4) "one-id"
}
You can use krsort
$array_1 = Array(4,2,1,3);
$array_2 = Array('four-id','two-id','one-id','three-id');
foreach ($array_1 as $key => $value) {
$array_merged[$value] = $array_2[$key];
}
krsort($array_merged);
foreach ($array_merged as $key => $value) {
$new_array_1[] = $key;
$new_array_2[] = $value;
}
echo '<pre>'.print_r( $new_array_1, true ).print_r( $new_array_2, true ).'</pre>';

Looking to create an associative array

I'm looking for a solution to create an associative array from an flat array data in foreach loop:
What i have is a csv/xls file that has header on first row and data in next rows.
Row1: header
Row2,3,4,5: data
the array looks:
array(3) {
[0]=>
array(7) {
[0]=>
string(3) "country"
[1]=>
string(7) "state"
[2]=>
string(3) "city"
[3]=>
string(5) "name"
[4]=>
string(4) "address"
[5]=>
string(6) "gender"
[6]=>
string(6) "status"
}
[1]=>
array(7) {
[0]=>
string(12) "Argentina"
[1]=>
string(12) "Corrientes"
[2]=>
string(12) "Corrientes"
[3]=>
string(12) "Jorge"
[4]=>
string(12) "Avenida Avellaneda 12"
[5]=>
string(12) "Masculino"
[6]=>
string(12) "Activo"
}
[2]=>
array(7) {
[0]=>
string(12) "Argentina"
[1]=>
string(12) "Chaco"
[2]=>
string(12) "Resistencia"
[3]=>
string(12) "Mariano"
[4]=>
string(12) "Avenida Peron 12"
[5]=>
string(12) "Masculino"
[6]=>
string(12) "Activo"
}
}
The result i need to get at the end is:
array(2) {
[0]=>
array(7) {
['country']=>
string(12) "Argentina"
['state']=>
string(12) "Corrientes"
['city']=>
string(12) "Corrientes"
['name']=>
string(12) "Jorge"
['address']=>
string(12) "Avenida Avellaneda 12"
['gender']=>
string(12) "Masculino"
['status']=>
string(12) "Activo"
}
[1]=>
array(7) {
['country']=>
string(12) "Argentina"
['state']=>
string(12) "Chaco"
['city']=>
string(12) "Resistencia"
['name']=>
string(12) "Mariano"
['address']=>
string(12) "Avenida Peron 12"
['gender']=>
string(12) "Masculino"
['status']=>
string(12) "Activo"
}
}
$array = $your_flat_array;
for ($i = 1; $i < count($array); $i++) {
$new_array[$i-1] = [];
foreach ($array[$i] as $key => $value) {
$new_array[$i-1][$array[0][$key]] = $value;
}
}
print_r($new_array);
create a multidimensional array from an flat array
You already have a multidimensional array, because you got arrays in an array.
What you can do in this specific case is to use array_splice() in combination with array_combine().
Try this:
$oldArray = array(
array( "country", "state", "city", "name" ),
array( "Argentina", "Corrientes", "Corrientes", "Jorge" ),
array( "Argentina", "Chaco", "Resistencia", "Mariano" )
);
$newArray = array_splice( $oldArray, 1 );
foreach( $newArray as $index => $array ) {
$newArray[$index] = array_combine( $oldArray[0], $array );
}
echo "<pre>";
var_dump( $newArray );
OUTPUT:
array(2) {
[0]=>
array(4) {
["country"]=>
string(9) "Argentina"
["state"]=>
string(10) "Corrientes"
["city"]=>
string(10) "Corrientes"
["name"]=>
string(5) "Jorge"
}
[1]=>
array(4) {
["country"]=>
string(9) "Argentina"
["state"]=>
string(5) "Chaco"
["city"]=>
string(11) "Resistencia"
["name"]=>
string(7) "Mariano"
}
}
All you have to do is remove the first item (header row) from your array:
array_splice($yourArray, 0, 1);

Categories