This is what my array looks like :
Array (
[0] => SimpleXMLElement Object (
[key] => Array (
[0] => Track ID
[1] => Name
[2] => Artist
[3] => Album Artist
[4] => Composer
[5] => Album
[6] => Genre
[7] => Kind
[8] => Size
[9] => Total Time
[10] => Disc Number
[11] => Disc Count
[12] => Track Number
[13] => Year
[14] => Date Modified
[15] => Date Added
[16] => Bit Rate
[17] => Sample Rate
[18] => Play Count
[19] => Play Date
[20] => Play Date UTC
[21] => Artwork Count
[22] => Persistent ID
[23] => Track Type
[24] => Location
[25] => File Folder Count
[26] => Library Folder Count )
[integer] => Array (
[0] => 2056
[1] => 3732918
[2] => 230661
[3] => 1
[4] => 1
[5] => 1
[6] => 1993
[7] => 128
[8] => 44100
[9] => 3
[10] => 3439412487
[11] => 1
[12] => 5
[13] => 1 )
[string] => Array (
[0] => Eye of the Tiger
[1] => Survivor
[2] => Survivor
[3] => Frankie Sullivan/Jim Peterik
[4] => Greatest Hits
[5] => Rock
[6] => MPEG audio file
[7] => 772F0F53F195E705
[8] => File
[9] => file://localhost/Users/cameron/Music/iTunes/iTunes%20Media/Music/Survivor/Greatest%20Hits/01%20Eye%20of%20the%20Tiger.mp3 )
[date] => Array (
[0] => 2012-08-27T17:01:00Z
[1] => 2012-08-27T17:01:03Z
[2] => 2012-12-27T07:21:27Z ) )
that's 1 result, there is about 50 of them repeated.
I am trying to select the artist value in this case : Frankie Sullivan/Jim Peterik
please note: there is about 50 other results that come after this first one, so I would like to do a foreach to display all results.
any suggestions? I am stuck.this is the code I used to get these results:
$xml = simplexml_load_file('Library.xml');
$xmlx = $xml->dict->dict->dict->key;
$artist = $xmlx->xpath("//dict[key='Artist']");
echo "<pre>" . print_r($artist, true) . "</pre>";
It seems that you have an array of SimpleXMLElement,
so you can iterate over your array and use the SimpleXMLElement facilities.
Try:
foreach($yourArray as $simpleXmlElement)
{
// Retrieve the name
echo $simpleXmlElement->string[3];
}
Take a look at the documentation for more question: SimpleXMLElement
For your specific problem, assuming the key and string are synchronized, you can try:
// Loop on your array of SimpleXMLElement
foreach($yourArray as $simpleXmlElement)
{
// Initialize the position and found value
$position = 0;
$found = false;
// Loop on the sub array 'key' and search the 'Artist Album' position
foreach($simpleXmlElement->key as $index => $value)
{
if ($value == "Album Artist")
{
$found = true;
break;
}
// Not found, increment position
$position++;
}
// Retrieve the name if found the artist album key
if ($found)
echo $simpleXmlElement->string[$position];
}
As
[3] => Album Artist
will give the position 3
Then, when retrieving the string value, it will return Frankie Sullivan/Jim Peterik
Related
I have a csv uploader i'm creating to push to an order api. Using phpSpreadsheets toArray method, i have an array like so:
Array
(
[0] => Array
(
[0] => product_sku
[1] => product_qty
[2] => shipping_name
[3] => shipping_address1
[4] => shipping_address2
[5] => shipping_city
[6] => shipping_county
[7] => shipping_postcode
[8] => shipping_type
[9] => customer_id
)
[1] => Array
(
[0] => test_sku_1
[1] => 3
[2] => Bruce Wayne
[3] => The Manor
[4] => Near Arkahm Asylumn
[5] => Gotham
[6] => Greater Gothan
[7] => B17MAN
[8] => 1
[9] => 14994333
)
[2] => Array
(
[0] => test_sku_2
[1] => 2
[2] => Bruce Wayne
[3] => The Manor
[4] => Near Arkahm Asylumn
[5] => Gotham
[6] => Greater Gothan
[7] => B17MAN
[8] => 1
[9] => 14994333
)
[3] => Array
(
[0] => test_sku_3
[1] => 7
[2] => Bruce Wayne
[3] => The Manor
[4] => Near Arkahm Asylumn
[5] => Gotham
[6] => Greater Gothan
[7] => L17MA2
[8] => 1
[9] => 14994333
)
)
Each order will be on a new line, however if a customer orders two different items, i need to group them together using their postcode. As such i was aiming to rearange into this format:
[orders] => Array(
Array(
[shipping_name] => "Bruce wayne",
[customer_id] => 14994333,
[address] => Array(
[shipping_address1] => "The Manor",
[shipping_address2] => "Near Arham Asylumn",
[shipping_city] => "Gotham",
[shipping_county] => "Greater Gotham",
[shipping_postcode] => "B17MAN",
)
[products] => Array(
Array(
[sku] => "test_sku_1",
[quantity] => 3
),
Array(
[sku] => "test_sku_2",
[quantity] => "2"
)
)
)
)
Once of the first problems i encountered was trying to match the postcodes. I managed to get a count using:
$getDuplicates = array_count_values(array_map(function($duplicates) {
return $duplicates[7]; //Where 7 is the postcode
}, $rows));
This worked in counting what i needed correctly. However from there i'm hitting a brick wall. If i'm counting the duplicates, i need it to also make a note of the rows it's already gone through so they aren't pushed incorrectly into the new array i want to make.
Pseudo it should be:
for each rows as row{
if row isn't set to be ignored{
for each count of this postcode{
array_push the product sku and qty
mark these rows as rows to be ignored
}
}
}
Can anyone help me with this?
So, long story short, i've been so caught up in this i completely missed the obvious. To solve this, i took the original array from phpspreadsheet and did an array_multisort:
foreach ($rows as $key => $row) {
$postcodes[$key] = $row[7]; //the postcode key
}
array_multisort($postcodes, SORT_DESC, $rows;
I then just worked my way through the array and if the postcode changed, i'd create a new array, otherwise i'd just push straight into the correct array for the products.
I feel really stupid i didn't think of this before. Thank you to #apokryfos for trying to help!
I am trying to figure a way to get this to work. But I have a hard time thinking out the logics.
I have this array:
Array
(
[0] => Array
(
[0] => news
[1] => {section}
[2] => {slug}
[3] => {*}
)
[1] => Array
(
[0] => {id}
[1] => {*}
)
[2] => Array
(
[0] => {date}
[1] => 25-07-1982
[2] => {section}
[3] => {slug}
[4] => {*}
)
)
That I need to convert to this result:
0 news/{id}/{date}
1 news/{id}/25-07-1982
2 news/{id}/{section}
3 news/{id}/{slug}
4 news/{id}/{*}
5 news/{*}/{date}
6 news/{*}/25-07-1982
7 news/{*}/{section}
8 news/{*}/{slug}
9 news/{*}/{*}
10 {section}/{id}/{date}
11 {section}/{id}/25-07-1982
12 {section}/{id}/{section}
13 {section}/{id}/{slug}
14 {section}/{id}/{*}
15 {section}/{*}/{date}
16 {section}/{*}/25-07-1982
17 {section}/{*}/{section}
18 {section}/{*}/{slug}
19 {section}/{*}/{*}
20 {slug}/{id}/{date}
21 {slug}/{id}/25-07-1982
22 {slug}/{id}/{section}
23 {slug}/{id}/{slug}
24 {slug}/{id}/{*}
25 {slug}/{*}/{date}
26 {slug}/{*}/25-07-1982
27 {slug}/{*}/{section}
28 {slug}/{*}/{slug}
29 {slug}/{*}/{*}
30 {*}/{id}/{date}
31 {*}/{id}/25-07-1982
32 {*}/{id}/{section}
33 {*}/{id}/{slug}
34 {*}/{id}/{*}
35 {*}/{*}/{date}
36 {*}/{*}/25-07-1982
37 {*}/{*}/{section}
38 {*}/{*}/{slug}
39 {*}/{*}/{*}
The input array could contain more than three keys, so the solution I'm looking for should be dynamic. And the result should have the same order as the result shown above.
Does someone know how to do this in a efficient way? Can someone give me a push in the right direction? Thanks a lot! :)
Sth like this
foreach ($array[0] as $val0 )
foreach ($array[1] as $val1 )
foreach ($array[2] as $val2 )
$newArray[] = "$val0/$val1/$val2";
EDIT: for variable array length
function recursive($array , $length = 0){
$retval =array();
if($length < count($array) -1){
foreach ($array[$length] as $val0 )
foreach (recursive($array, $length+1) as $val1)
$retval[] = "$val0/$val1";
}
else
{
foreach ($array[$length] as $val0 )
$retval[] = "$val0";
}
return $retval;
}
print_r(recursive($array));
Just because I like writing functions that mis/manage PHP arrays, I put this together, mainly because I was pretty sure you could avoid recursion — because the structure itself isn't recursive. (My head seems to think that is a rule, I'm sure someone somewhere can prove it wrong).
foreach ( array_reverse($array) as $sub ) {
if ( isset($rem) ) {
$ret = array();
foreach ( $sub as $itm ) {
foreach ( $rem as $val ) { $ret[] = "$itm/$val"; }
}
$rem = $ret;
}
else {
$rem = $sub;
}
}
The output found in $rem is as follows:
Array (
[0] => news/{id}/{date}
[1] => news/{id}/25-07-1982
[2] => news/{id}/{section}
[3] => news/{id}/{slug}
[4] => news/{id}/{*}
[5] => news/{*}/{date}
[6] => news/{*}/25-07-1982
[7] => news/{*}/{section}
[8] => news/{*}/{slug}
[9] => news/{*}/{*}
[10] => {section}/{id}/{date}
[11] => {section}/{id}/25-07-1982
[12] => {section}/{id}/{section}
[13] => {section}/{id}/{slug}
[14] => {section}/{id}/{*}
[15] => {section}/{*}/{date}
[16] => {section}/{*}/25-07-1982
[17] => {section}/{*}/{section}
[18] => {section}/{*}/{slug}
[19] => {section}/{*}/{*}
[20] => {slug}/{id}/{date}
[21] => {slug}/{id}/25-07-1982
[22] => {slug}/{id}/{section}
[23] => {slug}/{id}/{slug}
[24] => {slug}/{id}/{*}
[25] => {slug}/{*}/{date}
[26] => {slug}/{*}/25-07-1982
[27] => {slug}/{*}/{section}
[28] => {slug}/{*}/{slug}
[29] => {slug}/{*}/{*}
[30] => {*}/{id}/{date}
[31] => {*}/{id}/25-07-1982
[32] => {*}/{id}/{section}
[33] => {*}/{id}/{slug}
[34] => {*}/{id}/{*}
[35] => {*}/{*}/{date}
[36] => {*}/{*}/25-07-1982
[37] => {*}/{*}/{section}
[38] => {*}/{*}/{slug}
[39] => {*}/{*}/{*}
)
Also, for those that like their arrays multidimensional, this might come in handy (although I'd hate to think what the overheads are for such a code golfed version). Just to be clear, this second example doesn't create the string list as requested by the OP, but a hierarchical array structure instead.
foreach ( array_reverse($array) as $sub ) {
$rem = isset($rem)
? array_combine($sub, array_fill(0, count($sub), $rem))
: $sub
;
}
This generates (again in $rem):
Array (
[news] => Array (
[{id}] => Array (
[0] => {date}
[1] => 25-07-1982
[2] => {section}
[3] => {slug}
[4] => {*}
)
[{*}] => Array (
[0] => {date}
[1] => 25-07-1982
[2] => {section}
[3] => {slug}
[4] => {*}
)
)
[{section}] => Array (
[{id}] => Array (
[0] => {date}
[1] => 25-07-1982
[2] => {section}
[3] => {slug}
[4] => {*}
)
... and so on
Now if only PHP had a join_recursive that included keys.
(it would be almost pointless, save for helping with the above).
I have two arrays built from different directories that contain file names stripped of extensions. I want to find the ones that don't make a pair thus I merged the array to obtain the array below. How can I find the only non duplicate item in an array?
Array
(
[0] => dbbackup_2014.09.03_07_06_27
[1] => dbbackup_2014.09.03_07_07_08
[2] => dbbackup_2014.09.03_07_13_33
[3] => dbbackup_2014.09.03_07_15_24
[4] => dbbackup_2014.09.03_07_21_57
[5] => dbbackup_2014.09.03_07_22_11
[6] => dbbackup_2014.09.03_08_40_35
[7] => dbbackup_2014.09.03_08_41_36
[8] => dbbackup_2014.09.03_08_43_38
[9] => dbbackup_2014.09.04_04_59_08
[10] => dbbackup_2014.09.03_07_06_27
[11] => dbbackup_2014.09.03_07_07_08
[12] => dbbackup_2014.09.03_07_13_33
[13] => dbbackup_2014.09.03_07_15_24
[14] => dbbackup_2014.09.03_07_21_57
[15] => dbbackup_2014.09.03_07_22_11
[16] => dbbackup_2014.09.03_08_40_35
[17] => dbbackup_2014.09.03_08_41_36
[18] => dbbackup_2014.09.03_08_43_38
)
Note: it is [9]
$a = array_flip(array_filter(array_count_values($a),function($item){
return $item == 1 ? true : false;
}));
print_r($a);
Output
Array
(
[1] => dbbackup_2014.09.04_04_59_08
)
Ideone
foreach($array as $data)
{
$values=explode("_",$data);
$output[$values[1]]++;
}
foreach($output as $date=>$number)
{
if($number==1)
echo $date;
}
Output:
2014.09.04
Fiddle
I'm trying to organize my mysql table into a multidimension php tree array.
For example, I'm trying to organize my products in a hierarchy for easy selection to narrow down the result the narrower they go in the result.
I am returned mysql rows like this:
Array
(
[1] => Amazon
[2] => Kindle Fire
[3] =>
[4] =>
[5] =>
[6] =>
[7] =>
[8] =>
[9] => 1
)
Array
(
[1] => Amazon
[2] => Kindle Fire HD
[3] => WiFi
[4] => 7"
[5] =>
[6] => 16GB
[7] =>
[8] =>
[9] => 2
)
Array
(
[1] => Amazon
[2] => Kindle Fire HD
[3] => WiFi
[4] => 7"
[5] =>
[6] => 32GB
[7] =>
[8] =>
[9] => 3
)
Array
(
[1] => Amazon
[2] => Kindle Fire HD
[3] => WiFi
[4] => 8.9"
[5] =>
[6] => 16GB
[7] =>
[8] =>
[9] => 4
)
Array
(
[1] => Amazon
[2] => Kindle Fire HD
[3] => WiFi
[4] => 8.9"
[5] =>
[6] => 32GB
[7] =>
[8] =>
[9] => 5
)
Array
(
[1] => Amazon
[2] => Kindle Fire HD
[3] => 4G LTE
[4] => 8.9"
[5] =>
[6] => 32GB
[7] =>
[8] =>
[9] => 6
)
Array
(
[1] => Amazon
[2] => Kindle Fire HD
[3] => 4G LTE
[4] => 8.9"
[5] =>
[6] => 64GB
[7] =>
[8] =>
[9] => 7
)
Array
(
[1] => Amazon
[2] => Kindle Fire HDX
[3] => Wifi
[4] => 7"
[5] =>
[6] => 16GB
[7] =>
[8] =>
[9] => 8
)
Array
(
[1] => Amazon
[2] => Kindle Fire HDX
[3] => Wifi
[4] => 7"
[5] =>
[6] => 32GB
[7] =>
[8] =>
[9] => 9
)
Array
(
[1] => Amazon
[2] => Kindle Fire HDX
[3] => Wifi
[4] => 7"
[5] =>
[6] => 64GB
[7] =>
[8] =>
[9] => 10
)
...etc
Note the last array value is the Product ID.
And I'm looking for help writing a recursive function that will result in an array that looks like:
Array(
'Amazon' => Array(
'Kindle Fire' => 1,
'Kindle Fire HD' => Array(
'WiFi' => Array(
'7"' => Array(
'16GB' => 2,
'32GB' => 3
)
'8.9"' => Array(
'16GB' => 4,
'32GB' => 5
)
)
)
)
)
I've tried something like:
while($row = mysqli_fetch_row($res)) {
$id = $row[0];
unset($row[0]);
unset($row[count($row)]);
$row[] = $id; // Moves id to last array value
for($i = 1; $i < count($row); $i++) {
if($i == 1) {
if(!array_key_exists($row[$i], $data)) {
// Insert key
$data[$row[$i]] = array();
}
}
else {
$level = $data[$row[$i-1]];
if(array_key_exists($row[$i], $level)) {
// Key exists
}
else {
// Insert key
}
}
}
}
I think your code has a good intention: using $level to hold the current depth. But at the moment this won't work, because you are copying via $level = $data[$row[$i-1]]; - instead you need to refer to it, e.g. with $level =& $data[$row[$i-1]];.
$result = array();
while ($row = mysqli_fetch_row($res)) [
$id = array_shift($row);
if (!isset($maxIterator))
$maxIterator = count($row)-1;
$current =& $result;
for ($i=0; $i<$maxIterator; $i++) {
if (empty($row[$i]))
break;
if (!array_key_exists($row[$i], $current))
$current[ $row[$i] ] = array();
$current =& $current[ $row[$i] ];
}
//for properly ended and wasn't broken out of sooner
if ($i == $maxIterator) {
if (!array_key_exists($row[$i], $current))
$current[ $row[$i] ] = 1;
else
$current[ $row[$i] ]++;
}
}
array_shift basically does, what you needed two lines for: get the first element of an array and then remove it. Then I save the result of the count in a variable, so it doesn't need to be recalculated in every iteration of the for AND while.
Also I would suggest setting $maxIterator manually. With the shown result a good default would be 5. This way all values before the 5th. will be used for nesting and the 5th itself will be used to count (in your example this is storage size).
As the for will execute $i++ after the last iteration (and then it fails the condition and hence the loop breaks), it can be used for the counting.
Personally I would overthink what exactly you are doing and maybe use a specifc structure for that. However, this code should give you a good impression how it can be solved using references.
This is my $part_array:
Array (
[0] => 1015789
[1] => 1029402
[2] => 1031345
[3] => 1036476
[4] => 1061512
[5] => 1065031
[6] => 1069892
[7] => 1070721
[8] => 1073222
[9] => 1074811
)
$next_index = $next_index + 1;
$next_part = ($part_array[$next_index]);
Retrieve part# information using MySQL
Display part# and related information on page. Click on button to display next part# and related information and repeat until end, or user exits.
Each time I increment the $next_index and get the $next_part, the $part_array has the next part # added to the end of the array, so if I have read 3 records, my array now looks like this:
Array (
[0] => 1015789
[1] => 1029402
[2] => 1031345
[3] => 1036476
[4] => 1061512
[5] => 1065031
[6] => 1069892
[7] => 1070721
[8] => 1073222
[9] => 1074811
[10] => 1015789
[11] => 1029402
[12] => 1031345
)
How else could I do this without adding to the array? Does anyone have any suggestions? I am new to PHP and would greatly appreciate any advice.