Если это ваш первый визит, рекомендуем почитать справку по форуму. Для размещения своих сообщений необходимо зарегистрироваться. Для просмотра сообщений выберите раздел. |
[PHP] Выбрать элементы массива, где одинаковые другие ключи |
Философия, технологии, алгоритмы! |
|
Опции темы |
24.02.2012, 17:44 | #1 |
Форумец
Сообщений: 1,076
Регистрация: 27.11.2008
Возраст: 30
Не в сети |
[PHP] Выбрать элементы массива, где одинаковые другие ключи
В оригинале сложнее, но по аналогии вот массив:
$array = array( "0"=>array("name"=>"alex", "age"=>"10", "rost"=>"185"), "1"=>array("name"=>"roman", "age"=>"12", "rost"=>"185"), "2"=>array("name"=>"nik", "age"=>"10", "rost"=>"190"), "3"=>array("name"=>"james", "age"=>"14", "rost"=>"185"), "4"=>array("name"=>"valentine", "age"=>"10", "rost"=>"185")); Как мне получить данные основных (0,1,2,3,4) ключей, в которых одинаковые значения у age и rost. Т.е. нужна схема, когда на выходе будет array2, содержащий следующее $array = array( "0"=>array("name"=>"alex", "age"=>"10", "1"=>array("name"=>"valentine", "age"=>"10", "rost"=>"185")); |
24.02.2012, 17:49 | #2 |
Форумец
Сообщений: 1,076
Регистрация: 27.11.2008
Возраст: 30
Не в сети |
php .........
|
24.02.2012, 18:19 | #3 |
highly mean
Сообщений: 1,128
Регистрация: 26.05.2011
Возраст: 35
Не в сети |
Код:
<?php $people = array( array('name' => 'alex', 'age' => 10, 'height' => 185), array('name' => 'roman', 'age' => 12, 'height' => 185), array('name' => 'nik', 'age' => 10, 'height' => 190), array('name' => 'james', 'age' => 14, 'height' => 185), array('name' => 'valentine', 'age' => 10, 'height' => 185) ); $age = 10; $height = 185; $result = array_filter($people, function($person) use ($age, $height) { return $person['age'] == $age && $person['height'] == $height; }); print_r($result); Никто не знает, почему для кода прописана всякая хрень вида verdana,geneva,lucida,'lucida grande',arial,helvetica,sans-serif, но только не моноширинный шрифт? Последний раз редактировалось silly; 24.02.2012 в 18:41. Причина: ; пропустил |
24.02.2012, 18:34 | #4 |
Форумец
Сообщений: 1,076
Регистрация: 27.11.2008
Возраст: 30
Не в сети |
А не совсем что надо..
параметры age и рост неизвестны. Т.е. нужно получить массив - имена всех тех, у кого одинаковые (между ними) рост и вес? $people = array( array('name' => 'alex', 'age' => 10, 'height' => 185), array('name' => 'roman', 'age' => 12, 'height' => 185), array('name' => 'nik', 'age' => 10, 'height' => 190), array('name' => 'james', 'age' => 14, 'height' => 185), array('name' => 'vovka', 'age' => 12, 'height' => 185), array('name' => 'valentine', 'age' => 12, 'height' => 185), array('name' => 'igor', 'age' => 10, 'height' => 185), ); На выходе $people = array( array('names' => 'alex,igor', 'age' => 10, 'height' => 185), array('names' => 'roman,valentine,vovka', 'age' => 12, 'height' => 185), ); Последний раз редактировалось AlexanderSergeev; 24.02.2012 в 18:50. |
24.02.2012, 18:50 | #5 |
Форумец
Сообщений: 1,076
Регистрация: 27.11.2008
Возраст: 30
Не в сети |
с тем разобрался. только вот значения неизвестны. нужно весь массив на одинаковые проверит и имена сложить, грубо говоря.
|
24.02.2012, 19:17 | #6 |
highly mean
Сообщений: 1,128
Регистрация: 26.05.2011
Возраст: 35
Не в сети |
Прошу прощения за длинные названия переменных.
Код:
<?php $people = array( array('name' => 'alex', 'age' => 10, 'height' => 185), array('name' => 'roman', 'age' => 12, 'height' => 185), array('name' => 'nik', 'age' => 10, 'height' => 190), array('name' => 'james', 'age' => 14, 'height' => 185), array('name' => 'valentine', 'age' => 10, 'height' => 185) ); $names_grouped_by_age_height = array(); foreach ($people as $person) { $names_grouped_by_age_height[$person['age']][$person['height']][] = $person['name']; } $result = array(); foreach ($names_grouped_by_age_height as $age => $grouped_by_height) { foreach ($grouped_by_height as $height => $names) { $result[] = array( 'names' => join(',', $names), 'age' => $age, 'height' => $height); } } print_r($result); |
24.02.2012, 19:53 | #7 |
Форумец
Сообщений: 1,076
Регистрация: 27.11.2008
Возраст: 30
Не в сети |
Думал сам додумаю, но чето никак.
А если в другом массиве мне names (там числа) сложить все что нашлись нужно? 'names' => join(',', $names) на что поменять? |
24.02.2012, 19:56 | #8 |
Форумец
Сообщений: 1,076
Регистрация: 27.11.2008
Возраст: 30
Не в сети |
И спасибо огромное
|
24.02.2012, 20:00 | #9 |
Форумец
Сообщений: 1,076
Регистрация: 27.11.2008
Возраст: 30
Не в сети |
$people = array(
array('name' => '1', 'age' => 10, 'height' => 185), array('name' => '2', 'age' => 12, 'height' => 185), array('name' => '3', 'age' => 10, 'height' => 190), array('name' => '4', 'age' => 14, 'height' => 185), array('name' => '5', 'age' => 10, 'height' => 185), array('name' => '6', 'age' => 10, 'height' => 185), array('name' => '7', 'age' => 12, 'height' => 185), array('name' => '8', 'age' => 10, 'height' => 190), array('name' => '9', 'age' => 14, 'height' => 185), ); $names_grouped_by_age_height = array(); foreach ($people as $person) { $names_grouped_by_age_height[$person['age']][$person['height']][] = $person['name']; } $result = array(); foreach ($names_grouped_by_age_height as $age => $grouped_by_height) { foreach ($grouped_by_height as $height => $names) { $result[] = array( 'names' => array_sum($names), 'age' => $age, 'height' => $height); } } print_r($result); ПАШЕТ!спасибо за всё |
24.02.2012, 20:05 | #10 |
highly mean
Сообщений: 1,128
Регистрация: 26.05.2011
Возраст: 35
Не в сети |
Вот еще для сравнения вариант на ruby, традиционно более длинный, чем на php:
Код:
class Person attr_accessor :name, :age, :height def initialize(hash) hash.each do |k, v| self.send(k.to_s + '=', v) end end end class AutoVivHash < Hash alias_method :old_get, :[] def [](key, default = self.class) self[key] = default.new if not self.has_key?(key) self.old_get(key) end end people = [ Person.new(:name => 'alex', :age => 10, :height => 185), Person.new(:name => 'roman', :age => 12, :height => 185), Person.new(:name => 'nik', :age => 10, :height => 190), Person.new(:name => 'james', :age => 14, :height => 185), Person.new(:name => 'valentine', :age => 10, :height => 185) ] grouped = AutoVivHash.new people.each do |person| grouped[person.age][person.height, Array] << person.name end result = grouped.map do |age, by_height| by_height.map do |height, names| {:names => names.join(','), :age => age, :height => height} end end.flatten require'pp' pp result Последний раз редактировалось silly; 24.02.2012 в 20:25. Причина: косяк, однако |
24.02.2012, 20:16 | #11 |
Форумец
Сообщений: 1,076
Регистрация: 27.11.2008
Возраст: 30
Не в сети |
Да, чтобы было, пригодится я думаю.
|
24.02.2012, 20:40 | #12 |
Форумец
Сообщений: 1,076
Регистрация: 27.11.2008
Возраст: 30
Не в сети |
$people = array(
array('name' => '1','age' => 10,'height' => 185,'data' => 22), array('name' => '2','age' => 12,'height' => 185,'data' => 22), array('name' => '3','age' => 10,'height' => 190,'data' => 22), array('name' => '4','age' => 14,'height' => 185,'data' => 22), array('name' => '5','age' => 10,'height' => 185,'data' => 22), array('name' => '6','age' => 10,'height' => 185,'data' => 23), array('name' => '7','age' => 12,'height' => 185,'data' => 23), array('name' => '8','age' => 10,'height' => 190,'data' => 23), array('name' => '9','age' => 14,'height' => 185,'data' => 23), array('name' => '1','age' => 10,'height' => 185,'data' => 22), array('name' => '2','age' => 12,'height' => 185,'data' => 22), array('name' => '3','age' => 10,'height' => 190,'data' => 22), array('name' => '4','age' => 14,'height' => 185,'data' => 22), array('name' => '5','age' => 10,'height' => 185,'data' => 22), array('name' => '6','age' => 10,'height' => 185,'data' => 23), array('name' => '7','age' => 12,'height' => 185,'data' => 23), array('name' => '8','age' => 10,'height' => 190,'data' => 23), array('name' => '9','age' => 14,'height' => 185,'data' => 23) ); $names_grouped_by_data_age_height = array(); foreach ($people as $person) { $names_grouped_by_data_age_height[$person['data']][$person['age']][$person['height']][] = $person['name']; } $result = array(); foreach ($names_grouped_by_data_age_height as $data => $names_grouped_by_age_height) { foreach ($names_grouped_by_age_height as $age => $grouped_by_height) { foreach ($grouped_by_height as $height => $names) { $result[] = array( 'names' => join(',',$names), 'age' => $age, 'height' => $height, 'data' => $data); } } } print_r($result); хотел спрсоить, как чтобы по трем сортировать сделать, но сам разобрался. очень удобная кстати фишка $names_grouped_by_data_age_height[$person['data']][$person['age']][$person['height']][] = $person['name']; по порядку сортирует получается, сначала по дате, потом возрасту и высоте...принт_р помог разобраться. Спасибо еще раз. |
04.03.2012, 11:53 | #14 |
Кэп Улитка
Сообщений: 8,067
Регистрация: 04.05.2005
Возраст: 43
Не в сети |
AlexanderSergeev, ты случайно не преобразуешь данные после выборки из БД?
Если это так, то прекращай заниматься извращениями. На SQL твоя задача (исходная) решается так (мог наврать по запросу, т.к. проверить негде) Код:
select person_id, age, rost from peoples p where (age, rost) in (select age, rost from persons group by age, rost having count(*) > 1) order by age, rost |
04.03.2012, 12:45 | #15 |
highly mean
Сообщений: 1,128
Регистрация: 26.05.2011
Возраст: 35
Не в сети |
Не, в таком варианте это будет «select distinct age, height from people» и по одному запросу на каждую интересующую группу лиц.
Или нужно использовать соответствующие агрегирующие функции (вариант для sqlite): Код:
select age, height, group_concat(name) from people group by age, height |
04.03.2012, 13:26 | #16 |
Кэп Улитка
Сообщений: 8,067
Регистрация: 04.05.2005
Возраст: 43
Не в сети |
silly, его записи, не имеющие повторяющихся рост+год, вроде как не интересуют.
Если бы интересовали, то да - distinct подошел. Если база известна, напр. MySQL или sqlite, которые позволяют выполнять "странные" запросы, вида select id, value from t group by id То запрос можно упростить. |