How to merge array on behalf of a key value - php

I have an array
{
Array
(
[0] => Array
(
[filterType] => checkbox
[sfid] => a1d1I000000jrmwQAA
[name] => Publication Year
[specValues] => Array
(
[count] => 3
[value] => 1953
)
)
[1] => Array
(
[filterType] => checkbox
[sfid] => a1d1I000000jrmwQAA
[name] => Publication Year
[specValues] => Array
(
[count] => 1
[value] => 1954
)
)
)
}
But I want to merge array if sfid is same i.e i want result
{
Array
(
[0] => Array
(
[filterType] => checkbox
[sfid] => a1d1I000000jrmwQAA
[name] => Publication Year
[specValues] => Array(
[0] =>array(
[count] => 3
[value] => 1953
)
[1] =>array(
[count] => 1
[value] => 1954
)
)
)
)
}

You just need to iterate your array and add the row to the output if it is not in there already (you can use sfid as keys) and add specValues to the correct row.
<?php
$input = [
[
'filterType' => 'checkbox',
'sfid' => 'a1d1I000000jrmwQAA',
'name' => 'Publication Year',
'specValues' => [
'count' => 3,
'value' => 1953,
],
],
[
'filterType' => 'checkbox',
'sfid' => 'a1d1I000000jrmwQAA',
'name' => 'Publication Year',
'specValues' => [
'count' => 1,
'value' => 1954,
],
],
];
$data = [];
foreach ($input as $row) {
if (!isset($data[$row['sfid']])) {
$data[$row['sfid']] = [
'filterType' => $row['filterType'],
'sfid' => $row['sfid'],
'name' => $row['name'],
'specValues' => [],
];
}
$data[$row['sfid']]['specValues'][] = $row['specValues'];
}
var_dump(array_values($data));
Output:
array(1) {
[0]=>
array(4) {
["filterType"]=>
string(8) "checkbox"
["sfid"]=>
string(18) "a1d1I000000jrmwQAA"
["name"]=>
string(16) "Publication Year"
["specValues"]=>
array(2) {
[0]=>
array(2) {
["count"]=>
int(3)
["value"]=>
int(1953)
}
[1]=>
array(2) {
["count"]=>
int(1)
["value"]=>
int(1954)
}
}
}
}
I assume that if sfid is the same, then also filterType and name is the same.

Related

sort array according to other array's values

Here I have 2 array. One which provides sequence that is SortedArray and second that provides only data MyArrayUnsorted
I have SortedArray as a sequence that i need to print my data that is available in MyArrayUnsorted.
Remember the values are dynamic.
SortedArray
(
[0] => 8500
[1] => 8501
[2] => 8503
[3] => 8502
)
MyArrayUnsorted
(
[0] => array(
myid= '8500'
)
[1] => array(
myid= '8501'
)
[2] => array(
myid= '8502'
)
[3] => array(
myid= '8503'
)
)
FinalSortedArray
(
[0] => array(
myid= '8500'
)
[1] => array(
myid= '8501'
)
[2] => array(
myid= '8503'
)
[3] => array(
myid= '8502'
)
)
It looks pretty straightforward, you just need to array_flip the sorted array and usort the unsorted one.
<?php
declare(strict_types=1);
$sortedArray = [
'8500',
'8501',
'8503',
'8502',
];
$myArrayUnsorted = [
[
'myid' => '8500',
],
[
'myid' => '8501',
],
[
'myid' => '8502',
],
[
'myid' => '8503',
],
];
$flippedArray = array_flip($sortedArray);
usort($myArrayUnsorted, static function ($a, $b) use ($flippedArray) {
$aIndex = $flippedArray[$a['myid']] ?? null;
$bIndex = $flippedArray[$b['myid']] ?? null;
return $aIndex <=> $bIndex;
});
var_dump($myArrayUnsorted);
It would give the following output.
array(4) {
[0]=>
array(1) {
["myid"]=>
string(4) "8500"
}
[1]=>
array(1) {
["myid"]=>
string(4) "8501"
}
[2]=>
array(1) {
["myid"]=>
string(4) "8503"
}
[3]=>
array(1) {
["myid"]=>
string(4) "8502"
}
}

How to sort multidimensional array in PHP

I have tried almost all suggestions online, and I really can't figure out how to sort this SESSION array.
I want it sorted by "itemname"..
I have and want this output, but I need the itemname to determine which item array come first.
Array
(
[person] => Array
(
[namex] => Array
(
[itema] => Array
(
[itemid] => 43
[itemname] => def
)
[itemc] => Array
(
[itemid] => 33
[itemname] => abc
)
[itemg] => Array
(
[itemid] => 29
[itemname] => ghi
)
)
[namey] => Array
(
[itemj] => Array
(
[itemid] => 12
[itemname] => abc
)
[iteme] => Array
(
[itemid] => 44
[itemname] => jkl
)
[itemr] => Array
(
[itemid] => 20
[itemname] => rst
)
)
)
)
So, "person" stays the same, but name, item, itemid and itemname is always different.
Can anyone help me sort this by itemname?
I need the array to be like this, so can't change it up.
Also.. I need to access it later in a foreach, so I can print out the items.
As pointed out in the comments to the question the desired output is not really defined. You'd have to give a specific definition of the output, without that we have to assume what you probably are looking for:
<?php
$data = [
"person" => [
"namex" => [
"itema" => [
"itemid" => 43,
"itemname" => "def"
],
"itemc" => [
"itemid" => 33,
"itemname" => "abc"
],
"itemg" => [
"itemid" => 29,
"itemname" => "ghi"
]
],
"namey" => [
"itemj" => [
"itemid" => 12,
"itemname" => "abc"
],
"iteme" => [
"itemid" => 44,
"itemname" => "jkl"
],
"itemr" => [
"itemid" => 20,
"itemname" => "rst"
]
]
]
];
foreach ($data["person"] as $personName => &$person) {
uasort($person, function($a, $b) {
return $a["itemname"] > $b["itemname"];
});
}
print_r($data);
The obvious output is:
Array
(
[person] => Array
(
[namex] => Array
(
[itemc] => Array
(
[itemid] => 33
[itemname] => abc
)
[itema] => Array
(
[itemid] => 43
[itemname] => def
)
[itemg] => Array
(
[itemid] => 29
[itemname] => ghi
)
)
[namey] => Array
(
[itemj] => Array
(
[itemid] => 12
[itemname] => abc
)
[iteme] => Array
(
[itemid] => 44
[itemname] => jkl
)
[itemr] => Array
(
[itemid] => 20
[itemname] => rst
)
)
)
)
Assuming the input from the example is represented via array as:
<?php
$array = [
'person' => [
'namex' => [
'itema' => [
'itemid' => 43,
'itemname' => 'def'
],
'itemb' => [
'itemid' => 33,
'itemname' => 'abc'
],
'itemc' => [
'itemid' => 29,
'itemname' => 'ghi'
],
],
'namey' => [
'itema' => [
'itemid' => 12,
'itemname' => 'abc'
],
'itemb' => [
'itemid' => 44,
'itemname' => 'jkl'
],
'itemc' => [
'itemid' => 20,
'itemname' => 'rst'
],
],
]
];
You could do use array_multisort in a loop:
$ids = [];
foreach($array as $key => $value) {
foreach ($value as $newKey => $value2) {
$ids[$newKey] = array_column($value2, 'itemname');
array_multisort($ids[$newKey], SORT_NATURAL, $array[$key][$newKey]);
}
}
This will output
array(1) {
'person' =>
array(2) {
'namex' =>
array(3) {
'itemb' =>
array(2) {
'itemid' =>
int(33)
'itemname' =>
string(3) "abc"
}
'itema' =>
array(2) {
'itemid' =>
int(43)
'itemname' =>
string(3) "def"
}
'itemc' =>
array(2) {
'itemid' =>
int(29)
'itemname' =>
string(3) "ghi"
}
}
'namey' =>
array(3) {
'itema' =>
array(2) {
'itemid' =>
int(12)
'itemname' =>
string(3) "abc"
}
'itemb' =>
array(2) {
'itemid' =>
int(44)
'itemname' =>
string(3) "jkl"
}
'itemc' =>
array(2) {
'itemid' =>
int(20)
'itemname' =>
string(3) "rst"
}
}
}
}

formatting an array of array that contain similar key value

i have an array of arrays like this one
array(4) {
[0] => array(2) {
["option"] => string(5) "64310"
["choice"] => string(6) "221577"
}
[1] => array(2) {
["option"] => string(5) "64310"
["choice"] => string(6) "221578"
}
[2] => array(2) {
["option"] => string(5) "64305"
["choice"] => string(6) "221538"
}
}
i want to obtain a result like this one
array(2) {
[0] => array(2) {
["option"] => string(5) "64310"
["choices"] => array(2){
["choice"] => string(6) "221577"
["choice"] => string(6) "221578"
}
}
}
how can i proceed, thank you in advance
Something like this will help you achieve the desired result;
<?php
$data = [
[
'option' => '64310',
'choice' => '221577'
],
[
'option' => '64310',
'choice' => '221578'
],
[
'option' => '64305',
'choice' => '221538'
]
];
$res = [];
foreach($data as $d) {
// Check if we've already got this option
// Note the '&' --> Check link below
foreach($res as &$r) {
if (isset($r['option']) && $r['option'] === $d['option']) {
// Add to 'choices'
$r['choices'][] = $d['choice'];
// Skip the rest of both foreach statements
continue 2;
}
}
// Not found, create
$res[] = [
'option' => $d['option'],
'choices' => [ $d['choice'] ],
];
};
print_r($res);
& --> PHP "&" operator
Array
(
[0] => Array
(
[option] => 64310
[choices] => Array
(
[0] => 221577
[1] => 221578
)
)
[1] => Array
(
[option] => 64305
[choices] => Array
(
[0] => 221538
)
)
)
Try online!

Combine array with same element value and keep them all together, comma separated

I have a Multi-dimensional array
[0] => Array
(
[name] => Size
[value] => XS,S,XL
)
[1] => Array
(
[name] => Brand
[value] => Adidas
)
[2] => Array
(
[name] => Size
[value] => XS,XL,L,M
)
[3] => Array
(
[name] => Brand
[value] => Nike
)
i want result as
[0] => Array
(
[name] => Size
[value] => S,M,L,XS,XL
)
[1] => Array
(
[name] => Brand
[value] => Adidas,Nike
)
I'm trying to array_combine, array_merge and even array_unique with no success
You can try this -
$array = array(
'0' => array
(
'name' => 'Size',
'value' => 'XS,S,XL',
),
'1' => array
(
'name' => 'Brand',
'value' => 'Adidas',
),
'2' => array
(
'name' => 'Size',
'value' => 'XS,XL,L,M',
),
'3' => array
(
'name' => 'Brand',
'value' => 'Nike',
)
);
$temp = $new = array();
foreach($array as $val) {
$temp[$val['name']][] = $val['value'];
}
foreach($temp as $key => $value) {
// merge values, fetch unique, then merge again
$values = implode(',', array_unique(explode(',', implode(',', $value))));
$new[] = array('name' => $key, 'value' => $values); // store
}
var_dump($new);
Output
array(2) {
[0]=>
array(2) {
["name"]=>
string(4) "Size"
["value"]=>
string(11) "XS,S,XL,L,M"
}
[1]=>
array(2) {
["name"]=>
string(5) "Brand"
["value"]=>
string(11) "Adidas,Nike"
}
}
Demo

PHP - Remove duplicate values in an array based on a key's value and empty values

I have the following output from a PHP array:
Array (
[0] => Array (
[set1] => Array (
[link] => xyz.com/def
[time] => 2016-01-03
[set2] => Array (
[link] =>
[time] => )
[set3] => Array (
[link] =>
[time] => )
)
[1] => Array (
[set1] => Array (
[link] => xyz.com/123
[time] => 2016-01-03)
[set2] => Array (
[link] =>
[time] => )
[set3] => Array (
[link] => xyz.com/123
[time] => 2016-01-03)
)
[2] => Array (
[set1] => Array (
[link] => xyz.com/abc
[time] => 2015-12-03)
[set2] => Array (
[link] => xyz.com/abc
[time] => 2016-01-03)
[set3] => Array (
[link] => xyz.com/123456
[time] => 2016-01-03)
) )
I would like to eliminate duplicate [link] regardless of the [time] - then I would like to eliminate the empty [link] values such as [0][set2], and finally have an output as follows:
[link] => xyz.com/def
[time] => 2016-01-03
[link] => xyz.com/123
[time] => 2016-01-03)
[link] => xyz.com/abc
[time] => 2015-12-03
[link] => xyz.com/123456
[time] => 2016-01-03
This is what I tried:
$categoryUrlArray= array_unique(($categoryUrlArray, SORT_REGULAR);
foreach ($categoryUrlArray as $categoryUrlLevel01) {
$categoryUrlLevel01= array_unique($categoryUrlLevel01, SORT_REGULAR);
foreach ($categoryUrlLevel01 as $categoryUrlLevel02) {
echo $categoryUrlLevel02['link'];
echo '<br/>';
echo $categoryUrlLevel02['time'];
echo '<br/><br/><br/>';
}
}
The problem with the above code is that duplicates are not being eliminated and empty values are still showing i.e. there are plenty of line breaks <br/> - that is why I know they are not being eliminated.
how about just checking inside the inner loop for blanks and duplicates? then save them all inside a new variable. like this
$newArr = array();
$links = array();
foreach($categoryUrlArray as $urls){
foreach($urls as $url){
if(!empty($url['link']) && !in_array($url['link'],$links)){
$newArr[] = $url;
$links[] = $url['link'];
}
}
}
var_dump($newArr);
will result to
array(4) {
[0]=>
array(2) {
["link"]=>
string(11) "xyz.com/def"
["time"]=>
string(10) "2016-01-03"
}
[1]=>
array(2) {
["link"]=>
string(11) "xyz.com/123"
["time"]=>
string(10) "2016-01-03"
}
[2]=>
array(2) {
["link"]=>
string(11) "xyz.com/abc"
["time"]=>
string(10) "2015-12-03"
}
[3]=>
array(2) {
["link"]=>
string(14) "xyz.com/123456"
["time"]=>
string(10) "2016-01-03"
}
}
Just add a condition to check if link is not blank !empty($categoryUrlLevel02['link'])
Below is the modified code:
($categoryUrlArray= array_unique(($categoryUrlArray, SORT_REGULAR);
foreach ($categoryUrlArray as $categoryUrlLevel01) {
$categoryUrlLevel01= array_unique($categoryUrlLevel01, SORT_REGULAR);
foreach ($categoryUrlLevel01 as $categoryUrlLevel02) {
if(!empty($categoryUrlLevel02['link']))
{
echo $categoryUrlLevel02['link'];
echo '<br/>';
echo $categoryUrlLevel02['time'];
echo '<br/><br/><br/>';
}
}
}
Best practice for efficiently identifying unique values in your result array is accomplished by assigning temporary keys in the result array and checking !isset() for the identifying key (which is the link value). If you don't want to see these redundant/temporary keys in your output, call array_values().
*note, making iterated calls of in_array() is certainly more costly in terms of performance versus isset().
Code: (Demo)
$categoryUrlArray = [
[
"set1" => ["link" => "xyz.com/def", "time" => "2016-01-03"],
"set2" => ["link" => "", "time" => ""],
"set3" => ["link" => "", "time" => ""]
],
[
"set1" => ["link" => "xyz.com/123", "time" => "2016-01-03"],
"set2" => ["link" => "", "time" => ""],
"set3" => ["link" => "xyz.com/123", "time" => "2016-01-03"]
],
[
"set1" => ["link" => "xyz.com/abc", "time" => "2016-12-03"],
"set2" => ["link" => "xyz.com/abc", "time" => "2016-01-03"],
"set3" => ["link" => "xyz.com/123456", "time" => "2016-01-03"]
]
];
foreach ($categoryUrlArray as $groups) {
foreach ($groups as $row) {
if ($row["link"] && !isset($result[$row["link"]])) { if "truthy" (not empty) and unique
$result[$row["link"]] = $row;
}
}
}
var_export(array_values($result));
Output:
array (
0 =>
array (
'link' => 'xyz.com/def',
'time' => '2016-01-03',
),
1 =>
array (
'link' => 'xyz.com/123',
'time' => '2016-01-03',
),
2 =>
array (
'link' => 'xyz.com/abc',
'time' => '2016-12-03',
),
3 =>
array (
'link' => 'xyz.com/123456',
'time' => '2016-01-03',
),
)

Categories