$characters = [
"Character1" => ["Strength" => 1, "Dexterity" => 2,
"Intelligence" => 6, "Wisdom" => 6, "Charisma" => 3],
"Character2" => ["Strength" => 5, "Dexterity" => 4,
"Intelligence" => 1, "Wisdom" => 1, "Charisma" => 6],
"Character3" => ["Strength" => 6, "Dexterity" => 5,
"Intelligence" => 5, "Wisdom" => 1, "Charisma" => 5]
"Character4" => ["Strength" => 1, "Dexterity" => 2,
"Intelligence" => 4, "Wisdom" => 3, "Charisma" => 3]
];
So my question is as follows, how can I get the highest quality of each character. Like for Character1 it would be either Intelligence or Wisdom. I would like to echo the name of the character, the best quality and the value associated with the quality.
foreach($attributs as $s_key => $value)
{
if($value > $max)
$max = max($attributs);
$maxkey = $s_key;
}
echo "<li>$max , $maxkey</li>";
echo "</ul>";
I also have this code, but it only gives me the highest number for each character without giving me the name of the quality associated with the number.
foreach($characters as $names => $quality){
echo "$names";
echo max($quality);
}
I know none of them work at all, but that's as close as I could get to what I wanted.
You can find the highest value of an array using max function, meanwhile the key using array_search(). This will fail if you have 2 skills with the same value, assuming that "Intellegence" is 6 and "Wisdom" is 6 only "Intellegence" will be shown. Do you have to shown both of them or only one ?
$characters = [
"Character1" => ["Strength" => 1, "Dexterity" => 2, "Intelligence" => 6, "Wisdom" => 6, "Charisma" => 3],
"Character2" => ["Strength" => 5, "Dexterity" => 4, "Intelligence" => 1, "Wisdom" => 1, "Charisma" => 6],
"Character3" => ["Strength" => 6, "Dexterity" => 5, "Intelligence" => 5, "Wisdom" => 1, "Charisma" => 5],
"Character4" => ["Strength" => 1, "Dexterity" => 2, "Intelligence" => 4, "Wisdom" => 3, "Charisma" => 3]
];
foreach ($characters as $key => $character){
$value = max($character);
$skill = array_search($value, $character);
$characters[$key]['highest_skill'] = ['skill' => $skill, 'value' => $value];
}
print_r($characters["Character1"]);
// this will be shown
Array ( [Strength] => 1 [Dexterity] => 2 [Intelligence] => 6 [Wisdom] => 6 [Charisma] => 3 [highest_skill] => Array ( [skill] => Intelligence [value] => 6 ) )
Use a combination of max and array_search to get the highest for each character
Optionally, use a temp object were we will 'save' the highest key and value. This extra loop is shown in the demo, but can be removed if you move the echo after the array_search
<?php
$characters = [
"Character1" => ["Strength" => 1, "Dexterity" => 2, "Intelligence" => 6, "Wisdom" => 6, "Charisma" => 3],
"Character2" => ["Strength" => 5, "Dexterity" => 4, "Intelligence" => 1, "Wisdom" => 1, "Charisma" => 6],
"Character3" => ["Strength" => 6, "Dexterity" => 5, "Intelligence" => 5, "Wisdom" => 1, "Charisma" => 5],
"Character4" => ["Strength" => 1, "Dexterity" => 2, "Intelligence" => 4, "Wisdom" => 3, "Charisma" => 3]
];
$res = new \stdClass();
foreach ($characters as $name => $char) {
$highest = array_search(max($char), $char);
$res->{$name} = [ $highest, $char[$highest] ];
}
foreach ($res as $name => $val) {
echo "Highest for {$name} is {$val[0]}! Value: {$val[1]}" . PHP_EOL;
}
Output:
Highest for Character1 is Intelligence! Value: 6
Highest for Character2 is Charisma! Value: 6
Highest for Character3 is Strength! Value: 6
Highest for Character4 is Intelligence! Value: 4
Try it online!
Note: If there are multiple keys with the same (highest) value, the first will be used!
Though Ostone0 is right in his approach, but I assume it does not need to be this complicated. Just try the following to get what you want. It is easier and much more straightforward.
foreach ($characters as $character => $names) {
$quality = array_search(max($names), $names);
$max = max($names);
echo 'The highest value for '. $character . ' is ' . $max . ' for the quality ' . $quality. PHP_EOL ;
}
This will output the following:
The highest value for Character1 is 6 for the quality Intelligence
The highest value for Character2 is 6 for the quality Charisma
The highest value for Character3 is 6 for the quality Strength
The highest value for Character4 is 4 for the quality Intelligence
Try it online!
Related
Given the following multidimensional array:
$menu = [
'root' => [
'items' => [
'A' => [
'p' => [1, 2, 9],
],
'B' => [
'p' => [1, 2, 3, 9],
],
'C' => [
'p' => [1, 2, 4, 9],
],
'D' => [
'items' => [
'D1' => [
'p' => [1, 2, 3, 4, 9],
],
'D2' => [
'p' => [1, 2, 3, 4],
],
],
],
'E' => [
'items' => [
'E1' => [
'p' => [1, 2, 10],
],
],
],
'F' => [
'items' => [
'F1' => [
'p' => [5, 6],
],
'F2' => [
'p' => [7, 8],
],
],
],
],
],
];
Is there a way to get all the values in the 'p's as array, uniquely?
The output should be [1, 2, 9, 3, 4, 10, 5, 6, 7, 8]
I tried a simple one-liner, but it works only for the first level (A, B, C), nested $items are ignored:
$ps = array_unique(call_user_func_array('array_merge', array_column($menu['root']['items'], 'p')));
print_r($ps);
I also tried to write a recursive function, but I get totally stuck and the output is not what's expected
function recursive_ps($elem, $arr = []){
$output = $arr;
if (isset($elem['items'])){
foreach($elem['items'] as $key => $value){
if (isset($value['p'])){
$output = array_merge($arr, $value['p']);
if (isset($value['items'])){
return recursive_ps($value, $output);
}
}
}
}
return $output;
}
$o = recursive_ps($menu['root']);
print_r($o);
Please, any help?
The main issue is to return recursive_ps in the loop. You have to merge the returned data with the current array.
The second if to test $values['items'] shouldn't be inside the $value[p].
Also, $output = array_merge($arr, $value['p']); should be $output = array_merge($output, $value['p']); to combine to the current array.
Working code: (demo)
function recursive_ps($elem)
{
if (!isset($elem['items'])) {
return [];
}
$output = [];
foreach($elem['items'] as $key => $value) {
if (isset($value['p'])) {
$output = array_merge($output, $value['p']);
}
if (isset($value['items'])) {
// merge the return value of function
$output = array_merge($output, recursive_ps($value));
}
}
return $output;
}
$output = array_values(array_unique(recursive_ps($menu['root'])));
print_r($output);
Output:
Array
(
[0] => 1
[1] => 2
[2] => 9
[3] => 3
[4] => 4
[5] => 10
[6] => 5
[7] => 6
[8] => 7
[9] => 8
)
Another version using reference :
function recursive_ps($elem, &$arr = []) {
if (isset($elem['items'])) {
foreach($elem['items'] as $key => $value) {
if (isset($value['p'])) {
$arr = array_merge($arr, $value['p']);
}
if (isset($value['items'])) {
recursive_ps($value, $arr); // pass array by reference
}
}
}
}
$output = [];
recursive_ps($menu['root'], $output); // pass array by reference
print_r(array_values(array_unique($output)));
Please, consider the following arrays:
$reference = array(
'080604' => 4,
'080703' => 4,
'080734' => 2,
'080819' => 2,
'088341' => 2,
'805238' => 20,
'805283' => 4,
'805290' => 2,
'805849' => 2,
'806051' => 2,
'806068' => 2,
);
$test = array(
'080604' => 2,
'080703' => 4,
'080819' => 1,
'088341' => 2,
'805238' => 20,
'805283' => 4,
'805290' => 2,
'805849' => 2,
'806051' => 2,
'806068' => 2,
);
They are quite similar, but can have some various differences, e.g. it's possible that:
- some keys of $reference are not present in $test at all
- some keys of $test are not present in $reference at all
- all keys are present, but the values in $reference and $test are different (sometimes $reference value is bigger than $test and sometimes the value of $test is bigger than $reference)
I need to find out the differences automatically and to output them in a way, that not only the difference in count itself, but also a description is provided, e.g.
$result = [
'080604' => [
'reference' => 4,
'test' => 2
]
];
If some value is in only one of the lists:
$result = [
'1234567890' => [
'reference' => 0,
'test' => 2
]
];
or something like that.
Does someone have an idea, which is the best way to accomplish this in an elegant way? Thank you very much!
Iterate over each and populate the array with values if present:
$combined = [];
foreach ($reference as $key => $val) {
$combined[$key] = [
'test' => 0,
'reference' => $val,
];
}
foreach ($test as $key => $val) {
if (!isset($combined[$key])) {
$combined[$key] = [
'reference' => 0,
'test' => 0,
]
}
$combined[$key]['test'] = $val;
}
$combined will contain both values from both arrays with reference to both the elements from $reference and $test.
try
$result = array_diff($reference, $test);
print_r($result)
How I can check if multi array keys exist?
Example:
$array = array(
array('first_id' => 2, 'second_id' => 4, 'third_id' => 6),
array('first_id' => 3, 'second_id' => 5, 'third_id' => 7)
);
And now I want to check if in array exist row with params:
first_id = 3,
second_id = 5,
third_id = 6.
in this example, I should get no results, becase third_id = 6 is not exist (it exist but with first_id = 2 and second_id = 4).
How I can check it in easy way in PHP?
Thanks.
PHP's native array equality check will return true for arrays that have the same keys and values, so you should just be able to use in_array for this - it will take care of the "depth" automatically:
$set = [
['first_id' => 2, 'second_id' => 4, 'third_id' => 6],
['first_id' => 3, 'second_id' => 5, 'third_id' => 7]
];
$tests = [
['first_id' => 3, 'second_id' => 5, 'third_id' => 7],
['first_id' => 3, 'second_id' => 5, 'third_id' => 6],
['first_id' => 2, 'second_id' => 4, 'third_id' => 6],
['first_id' => 2, 'second_id' => 5, 'third_id' => 6],
];
foreach ($tests as $test) {
var_dump(in_array($test, $set));
}
bool(true)
bool(false)
bool(true)
bool(false)
See https://eval.in/936215
If it's important that the array keys are also in the right order, add the third paramater true to the in_array call. This will use strict equality, rather than loose, and require the arrays to be ordered identically. See the information about equality here: http://php.net/manual/en/language.operators.array.php
You can use isset, array_search, and array_filter
for only one liner try this..
$array = array(
array('first_id' => 2, 'second_id' => 4, 'third_id' => 6),
array('first_id' => 3, 'second_id' => 5, 'third_id' => 7)
);
$first_id = 2;
$second_id = 4;
$third_id = 6;
//check and get array index if exist
$index = array_keys(array_filter($array, function($item) use ($first_id,
$second_id, $third_id) { return $item['first_id'] === $first_id &&
$item['second_id'] === $second_id && $item['third_id'] === $third_id; }));
//print out that array index
print_r($array[$index[0]]);
Here's the game : Hashiwokakero.
To solve it, I need to find all possible combinations of links + islands around every island.
Constraints are, 1 or 2 links, and one combination is enough links created for the targeted island.
For example, I have a island ['A' => 3], which means it needs 3 links to be solved, and it has 3 neighbors ['B', 'C', 'D'].
I'd like to find an algorithm which would produce such an array :
[
['B' => 1, 'C' => 1, 'D' => 1],
['B' => 1, 'C' => 2],
['B' => 1, 'D' => 2],
['B' => 2, 'C' => 1],
['B' => 2, 'D' => 1],
['C' => 1, 'D' => 2],
['C' => 2, 'D' => 1]
];
Thanks.
If you want to find all combinations of links (0, 1, or 2) per neighbor, with a fixed total number of links, then you could use the following recursive function:
function getPossibleLinks($value, $neighbors) {
if ($value == 0) return [[]];
$max = min(2, $value);
$min = 2 - min(count($neighbors) * 2 - $value, 2);
if ($min > 2) {
throw new Exception('Not possible to assign that many links');
}
$results = [];
for ($count = $min; $count <= $max; $count++) {
$nextResults = getPossibleLinks($value - $count, array_slice($neighbors, 0, -1));
foreach($nextResults as $result) {
if ($count) $result[end($neighbors)] = $count;
$results[] = $result;
}
}
return $results;
}
You would need to pass it the number of links as first argument ($value), and the array of neighbors as an array of strings.
Here is an example call:
$results = getPossibleLinks(3, ["B", "C", "D"]);
After this call, $results will have this content:
[
['B' => 2, 'C' => 1],
['B' => 1, 'C' => 2],
['B' => 2, 'D' => 1],
['B' => 1, 'C' => 1, 'D' => 1],
['C' => 2, 'D' => 1],
['B' => 1, 'D' => 2],
['C' => 1, 'D' => 2]
]
See it run on eval.in.
I have two associative arrays I wish to combine with a foreach loop:
$arr1 = array( 'wikipedia.org' => 11, 'bing.com' => 9, 'google.com' => 8, 'blekko.com' => 7, 'groove.com' => 6, 'blo.com' => 5, 'ekko.com' => 4, 'rokko.com' => 3, 'always.com' => 2, 'popo.com' => 1);
$arr2 = array( 'google.com' => 20, 'blekko.com' => 19, 'wikipedia.org' => 8, 'bing.com' => 7, 'blo.com' => 6, 'ekko.com' => 5, 'groove.com' => 4, 'popo.com' => 3, 'always.com' => 2, 'rokko.com' => 1);
I use a new array
$combined = $arr1;
with a foreach loop
foreach($arr2 as $key=>$value)
{
array_push($combined,$value);
}
... which adds the value but not the key. I think I know why, but cannot find a way to add the key and the value. This works for a single line, but frustratingly nor in a foreach loop!
$combined=array_merge(array('blovk.com'=>'44'),$combined);
$aggregatedResults[$key] = $value;
It should be that simple...