Using xPath query, I am trying to extract HTML values and put them into an associative array in PHP. I am using a loop to get the rows and cells from the table. But, I can;t figure out how to get the cells in an array embedded within an array that represents the row. Basically, just transferring the table structure to an array. Ideally, it would help to assign keys for the cell data.
I tried combining $key as an array and a counter to assign key/value pair. I and xpath at different points of the structure. I can get fill up the array but I am But I just can't seem to crack it.
$cells = array();
$cell_values = array();
$key = array("MM", "DD", "TIME", "WVHT", "SwH", "SwP", "SwD", "WWH", "WWP", "WWD", "STEEPNESS", "APD");
$i = 3;
while($i <= 5){
$rows = $xpath->query('//table[#class="dataTable"][2]/tr['.$i.']');
if (!is_null($rows)){
foreach ($rows as $row) {
$cells = $row->getElementsByTagName('td');
$i++;
foreach ($cells as $cell) {
$cell_values[] = $cell->nodeValue;
$dataOut[] = array_combine($key, $cell_values);
}
}
}
}
Expected:
Array ( [0] => [1] => [2] => [3] => [4] => [5] => [6] => [7] => [8] => [9]
=> [10] =>
[11] => Array ( [MM] => 02 [DD] => 17 [TIME] => 11:30 am [WVHT]
=> 3.0 [SwH] => 0.3 [SwP] => 10.5 [SwD] => SE [WWH] => 2.6 [WWP] => 8.3
[WWD] => SE [STEEPNESS] => AVERAGE [APD] => 4.4 )
//Next set of row data with $keys
[12] => Array ( [MM] => 02 [DD] => 17 [TIME] => 11:00 am [WVHT] => 3.3 [SwH]
=> 0.3 [SwP] => 10.5 [SwD] => SE [WWH] => 2.6 [WWP] => 8.3 [WWD] => SE
[STEEPNESS] => AVERAGE [APD] => 4.4 )
[13] => Array... etc.
What I Get:
Array ( [0] => [1] => [2] => [3] => [4] => [5] => [6] => [7] => [8] => [9]
=> [10] => [11] => Array ( [MM] => 02 [DD] => 17 [TIME] => 11:30 am [WVHT]
=> 3.0 [SwH] => 0.3 [SwP] => 10.5 [SwD] => SE [WWH] => 2.6 [WWP] => 8.3
[WWD] => SE [STEEPNESS] => AVERAGE [APD] => 4.4 ) [12] => [13] => [14] =>
[15] => [16] => [17] => [18] => [19] => [20] => [21] => [22] => [23] => [24]
=> [25] => [26] => [27] => [28] => [29] => [30] => [31] => [32] => [33] =>
[34] => [35] => )
If you define your keys as values in the $key array rather than keys, you can array_combine that with the values from the <td>s to produce the rows for your result array.
$rows = $xpath->query('//table[#class="dataTable"][2]/tr');
// define these as values so you can use them in array_combine
$key = array("WVHT", "SwH", "SwD", "WWH", "WWP", "WWD", "STEEPNESS", "AMD");
$data = array();
$cells = array();
if (!is_null($rows)) {
foreach ($rows as $row) {
$cells = $row->getElementsByTagName('td');
// get all the cell values from the row
$row_values = [];
foreach ($cells as $cell) {
$row_values[] = $cell->nodeValue;
}
// combine the keys with the values for this row and add the row to $data
$data[] = array_combine($key, $row_values);
}
}
I'm querying a database to get this array. The output is an account number followed by the amount for that account number. As you can see there are duplicate instances of the account number. This array will always be the same, ie account number and then amount. How do I get a total of a single account number? For example the total amount for 1B2 is $10119.59.
Array
(
[0] => 1B2
[1] => 1970.40
[2] => 1B2
[3] => 1493.60
[4] => 1B2
[5] => 1400.25
[6] => J014 1
[7] => 1423.20
[8] => J014 1
[9] => 2179.20
[10] => J014 1
[11] => 1432.00
[12] => J014 1
[13] => 711.60
[14] => 1B2
[15] => 298.72
[16] => 1B2
[17] => 1568.80
[18] => 1B2
[19] => 1822.62
[20] => 1B2
[21] => 1493.60
[22] => J014 1
[23] => 1400.25
[24] => 1B2
[25] => 711.60
[26] => J014 1
[27] => 1194.88
[28] => J014 1
[29] => 1493.60
)
Here is one way to do it using a bunch of array functions.
$your_account = '1B2';
$total = array_sum(array_column(array_filter(
array_chunk($array, 2), function($v, $k) use ($your_account) {
return $v[0] == $your_account;
}, ARRAY_FILTER_USE_BOTH), 1));
Working from inside to outside:
array_chunk creates a two dimensional array of account entries
array_filter filters the array to only entries for your account
array_column gets only the amount column
array_sum totals the
amounts
You can use the following code:
$data = [
0 => '1B2',
1 => '1970.40',
2 => '1B2',
3 => '1493.60',
4 => '1B2',
5 => '1400.25',
6 => 'J014 1',
7 => '1423.20',
8 => 'J014 1',
9 => '2179.20',
10 => 'J014 1',
11 => '1432.00',
12 => 'J014 1',
13 => '711.60',
14 => '1B2',
15 => '298.72',
16 => '1B2',
17 => '1568.80',
18 => '1B2',
19 => '1822.62',
20 => '1B2',
21 => '1493.60',
22 => 'J014 1',
23 => '1400.25',
24 => '1B2',
25 => '711.60',
26 => 'J014 1',
27 => '1194.88',
28 => 'J014 1',
29 => '1493.60',
];
$temp = array();
$i = 0;
$account_key = '';
foreach($data as $key => $value) {
if ($i % 2 == 0) { //This is the account number
$account_key = $value;
} else { //This is the amount
$temp[$account_key][] = $value;
}
$i++;
}
foreach($temp as $key => $value) { //For each account number sum the amount
echo $key.': '.array_sum($value).'<br />';
}
Result:
1B2: 10759.59
J014 1: 9834.73
I have two arrays:
1- Id person (key) and qualification (value), this array have a descending order : arsort
Array
(
[61] => 02.30.00
[95] => 02.30.00
[19] => 02.01.00
[131] => 02.00.00
[58] => 01.60.00
[97] => 01.50.00
[76] => 01.40.00
[20] => 01.30.00
[112] => 01.10.00
[42] => 01.10.00
[116] => 01.04.00
}
2- ... and attempts associated to the Id person.
Array
(
[131] => 1
[58] => 1
[61] => 1
[112] => 2
[116] => 1
[42] => 1
[19] => 1
[20] => 1
[76] => 1
[97] => 1
[95] => 1
)
I need to maintain the descending order but adding ascending order by the number of the attempts. My problem is with these values:
[112] => 01.10.00 | 2
[42] => 01.10.00 | 1
How get this result?
Array
(
[61] => 02.30.00 // 1
[95] => 02.30.00 // 1
[19] => 02.01.00 // 1
[131] => 02.00.00 // 1
[58] => 01.60.00 // 1
[97] => 01.50.00 // 1
[76] => 01.40.00 // 1
[20] => 01.30.00 // 1
[42] => 01.10.00 // 1
[112] => 01.10.00 // 2
[116] => 01.04.00 // 1
)
Edit: ugly solution:
$new = array();
foreach($qualification as $k => $r)
{
$new[$k] = array(
'qualification'=> $r,
'attempt' => $attempt[$k],
'id' => $k,
);
}
foreach ($new as $key => $row)
{
$qlf[$key] = $row['qualification'];
$att[$key] = $row['attempt'];
}
array_multisort($qlf, SORT_DESC, $att, SORT_ASC, $new);
$result = array();
foreach ($new as $row)
{
$result[$row['id']] = $row['qualification'];
}
print_r($result);
uksort($qualification, function ($a, $b) use ($qualification, $attempt) {
return strcmp($qualification[$a], $qualification[$b])
?: $attempt[$a] - $attempt[$b];
});
I'm not entirely sure about which order you want to sort what in, but the above code will do; you just may have to switch $a and $b for reversing the order of one or the other.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have been coding and improving the code jszobody provided me that can found on this LINK which It makes me to be my refference but it results me to an error Fatal error: Using $this when not in object context
PHP:
<?php
function getAllPossiblePermutations($mdArray, $firstTime=true, $tempArray=array())
{
// initialize results array
if ($firstTime)
{
$this->permutationsResultsArray = array();
}
// find first sub array and iterate through it
$thisArray = array_shift($mdArray);
foreach ($thisArray as $key => $elem)
{
// if this number has already been used skip this possible permutation
if (in_array($elem, $tempArray))
{
continue;
}
$tempArray[] = $elem;
if (count($mdArray) == 0)
{
$this->permutationsResultsArray[] = $tempArray;
}
else
{
$this->getAllPossiblePermutations($mdArray, false, $tempArray);
}
array_pop($tempArray);
}
}
$traits = array
(
array('Happy', 'Sad', 'Angry', 'Hopeful'),
array('Outgoing', 'Introverted'),
array('Tall', 'Short', 'Medium'),
array('Handsome', 'Plain', 'Ugly')
);
print_r(getAllPossiblePermutations($traits));
?>
EXPECTED OUTPUT:
Array ( [0] => HappyOutgoingTallHandsome 1 => HappyOutgoingTallPlain [2] => HappyOutgoingTallUgly [3] => HappyOutgoingShortHandsome [4] => HappyOutgoingShortPlain [5] => HappyOutgoingShortUgly [6] => HappyOutgoingMediumHandsome [7] => HappyOutgoingMediumPlain [8] => HappyOutgoingMediumUgly [9] => HappyIntrovertedTallHandsome [10] => HappyIntrovertedTallPlain [11] => HappyIntrovertedTallUgly [12] => HappyIntrovertedShortHandsome [13] => HappyIntrovertedShortPlain [14] => HappyIntrovertedShortUgly [15] => HappyIntrovertedMediumHandsome [16] => HappyIntrovertedMediumPlain [17] => HappyIntrovertedMediumUgly [18] => SadOutgoingTallHandsome [19] => SadOutgoingTallPlain [20] => SadOutgoingTallUgly [21] => SadOutgoingShortHandsome [22] => SadOutgoingShortPlain [23] => SadOutgoingShortUgly [24] => SadOutgoingMediumHandsome [25] => SadOutgoingMediumPlain [26] => SadOutgoingMediumUgly [27] => SadIntrovertedTallHandsome [28] => SadIntrovertedTallPlain [29] => SadIntrovertedTallUgly [30] => SadIntrovertedShortHandsome [31] => SadIntrovertedShortPlain [32] => SadIntrovertedShortUgly [33] => SadIntrovertedMediumHandsome [34] => SadIntrovertedMediumPlain [35] => SadIntrovertedMediumUgly [36] => AngryOutgoingTallHandsome [37] => AngryOutgoingTallPlain [38] => AngryOutgoingTallUgly [39] => AngryOutgoingShortHandsome [40] => AngryOutgoingShortPlain [41] => AngryOutgoingShortUgly [42] => AngryOutgoingMediumHandsome [43] => AngryOutgoingMediumPlain [44] => AngryOutgoingMediumUgly [45] => AngryIntrovertedTallHandsome [46] => AngryIntrovertedTallPlain [47] => AngryIntrovertedTallUgly [48] => AngryIntrovertedShortHandsome [49] => AngryIntrovertedShortPlain [50] => AngryIntrovertedShortUgly [51] => AngryIntrovertedMediumHandsome [52] => AngryIntrovertedMediumPlain [53] => AngryIntrovertedMediumUgly [54] => HopefulOutgoingTallHandsome [55] => HopefulOutgoingTallPlain [56] => HopefulOutgoingTallUgly [57] => HopefulOutgoingShortHandsome [58] => HopefulOutgoingShortPlain [59] => HopefulOutgoingShortUgly [60] => HopefulOutgoingMediumHandsome [61] => HopefulOutgoingMediumPlain [62] => HopefulOutgoingMediumUgly [63] => HopefulIntrovertedTallHandsome [64] => HopefulIntrovertedTallPlain [65] => HopefulIntrovertedTallUgly [66] => HopefulIntrovertedShortHandsome [67] => HopefulIntrovertedShortPlain [68] => HopefulIntrovertedShortUgly [69] => HopefulIntrovertedMediumHandsome [70] => HopefulIntrovertedMediumPlain [71] => HopefulIntrovertedMediumUgly [72] => )
where did I go wrong?
You have a lot of referemces to class variables, like this:
$this->permutationsResultsArray = array();
And PHP complains since this function is not a method in a class. It will work if you just remove this-> so you get:
$permutationsResultsArray = array();
In addition when you are all done you never really return the result.. Like this:
return $permutationsResultsArray;
There is a problem with it though. You are recusing and you don't create that array except in the first round but your code uses it as if it was defined.
BTW: Your function could be much easier with 3 foreach loops:
function getCombinations($traits)
{
$combinations = array('');
foreach( $traits as $trait_level ) {
$new_combinations = array();
foreach ( $combinations as $comb ) {
foreach ( $trait_level as $trait ){
$new_combinations[] = "$comb $trait";
}
}
$combinations = $new_combinations;
}
return $combinations;
}
A function doesn't have a self referential $this. Actually, removing all your $this-> references and make $tempArray a pass by reference instead of by value, your code should work...
function getAllPossiblePermutations($mdArray, $firstTime=true, &$tempArray=array())
I have an array that I use a loop to run throught, the code below:
foreach($arry as $parentkey => $parentvalue){
$secondloop = explode(",",$parentvalue);
foreach($secondloop as $childvalue){
echo $parentkey.' '.$childvalue ;
}
}
When I run it, it does not display the parentkey. Does php not support that kind of loop?
How do I make it display the parent key? What would be the best way to walk throught the loop to get the desired result?
original array
Array ( [1] => 2,3,10,11,27,28,35,36,165,37,38,40,41,42,43,44,46,49,50,61,62,65,66,75,67,71,69,72,73,74,76,96,90,91,97,107,118,147,119,122,139,142,148,149,168,169,170,171,172,173,174,181 [2] => 39,102,94,98,92,121 [3] => 45,77,117,103,109,99 [4] => 47,78,146,105,113,115,104 [5] => 48,79,106,114,120,110 [6] => 68,93,116,111,112 [7] => 140,150 [8] => 141,151 [9] => 143,144,166,153 [10] => 145,154,159 [11] => 157,155 [12] => 158,156 [13] => 160 [14] => 161 [15] => 162 [16] => 163 [17] => 164 )
Given the information given, your code works, see the following cleaned up example.
<?php
$arry = array(
1 => '2,3,10,11,27,28,35,36,165,37,38,40,41,42,43,44,46,49,50,61,62,65,66,75,67,71,69,72,73,74,76,96,90,91,97,107,118,147,119,122,139,142,148,149,168,169,170,171,17$
2 => '39,102,94,98,92,121',
3 => '45,77,117,103,109,99',
4 => '47,78,146,105,113,115,104',
5 => '48,79,106,114,120,110',
6 => '68,93,116,111,112',
7 => '140,150',
8 => '141,151',
9 => '143,144,166,153',
10 => '145,154,159',
11 => '157,155',
12 => '158,156',
13 => '160',
14 => '161',
15 => '162',
16 => '163',
17 => '164'
);
foreach($arry as $parentkey => $parentvalue){
$secondloop = explode(",",$parentvalue);
foreach($secondloop as $childvalue){
echo 'Parent key: ' . $parentkey . ', child value: ' . $childvalue . PHP_EOL;
}
}