Большой Воронежский Форум

Если это ваш первый визит, рекомендуем почитать справку по форуму. Для размещения своих сообщений необходимо зарегистрироваться. Для просмотра сообщений выберите раздел.
Вернуться   Большой Воронежский Форум » Компьютеры и все, что с ними связано » » Программирование
Философия, технологии, алгоритмы!

Ответ
 
Опции темы
Старый 24.02.2012, 17:44   #1   
Форумец
 
Аватар для AlexanderSergeev
 
Сообщений: 1,076
Регистрация: 27.11.2008
Возраст: 30

AlexanderSergeev вне форума Не в сети
[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   
Форумец
 
Аватар для AlexanderSergeev
 
Сообщений: 1,076
Регистрация: 27.11.2008
Возраст: 30

AlexanderSergeev вне форума Не в сети
php .........
  Ответить с цитированием
Старый 24.02.2012, 18:19   #3   
highly mean
 
Сообщений: 1,128
Регистрация: 26.05.2011
Возраст: 35

silly вне форума Не в сети
Код:
<?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   
Форумец
 
Аватар для AlexanderSergeev
 
Сообщений: 1,076
Регистрация: 27.11.2008
Возраст: 30

AlexanderSergeev вне форума Не в сети
А не совсем что надо..
параметры 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   
Форумец
 
Аватар для AlexanderSergeev
 
Сообщений: 1,076
Регистрация: 27.11.2008
Возраст: 30

AlexanderSergeev вне форума Не в сети
с тем разобрался. только вот значения неизвестны. нужно весь массив на одинаковые проверит и имена сложить, грубо говоря.
  Ответить с цитированием
Старый 24.02.2012, 19:17   #6   
highly mean
 
Сообщений: 1,128
Регистрация: 26.05.2011
Возраст: 35

silly вне форума Не в сети
Прошу прощения за длинные названия переменных.

Код:
<?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   
Форумец
 
Аватар для AlexanderSergeev
 
Сообщений: 1,076
Регистрация: 27.11.2008
Возраст: 30

AlexanderSergeev вне форума Не в сети
Думал сам додумаю, но чето никак.

А если в другом массиве мне names (там числа) сложить все что нашлись нужно?
'names' => join(',', $names)

на что поменять?
  Ответить с цитированием
Старый 24.02.2012, 19:56   #8   
Форумец
 
Аватар для AlexanderSergeev
 
Сообщений: 1,076
Регистрация: 27.11.2008
Возраст: 30

AlexanderSergeev вне форума Не в сети
И спасибо огромное
  Ответить с цитированием
Старый 24.02.2012, 20:00   #9   
Форумец
 
Аватар для AlexanderSergeev
 
Сообщений: 1,076
Регистрация: 27.11.2008
Возраст: 30

AlexanderSergeev вне форума Не в сети
$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

silly вне форума Не в сети
Вот еще для сравнения вариант на 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   
Форумец
 
Аватар для AlexanderSergeev
 
Сообщений: 1,076
Регистрация: 27.11.2008
Возраст: 30

AlexanderSergeev вне форума Не в сети
Да, чтобы было, пригодится я думаю.
  Ответить с цитированием
Старый 24.02.2012, 20:40   #12   
Форумец
 
Аватар для AlexanderSergeev
 
Сообщений: 1,076
Регистрация: 27.11.2008
Возраст: 30

AlexanderSergeev вне форума Не в сети
$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'];
по порядку сортирует получается, сначала по дате, потом возрасту и высоте...принт_р помог разобраться.

Спасибо еще раз.
  Ответить с цитированием
Старый 24.02.2012, 21:20   #13   
highly mean
 
Сообщений: 1,128
Регистрация: 26.05.2011
Возраст: 35

silly вне форума Не в сети
Э… Нет, как раз сортировки здесь и нет, только объединение «по общим интересам».
  Ответить с цитированием
Старый 04.03.2012, 11:53   #14   
Кэп Улитка
 
Аватар для Yandex
 
Сообщений: 8,067
Регистрация: 04.05.2005
Возраст: 43

Yandex вне форума Не в сети
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

silly вне форума Не в сети
Не, в таком варианте это будет «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   
Кэп Улитка
 
Аватар для Yandex
 
Сообщений: 8,067
Регистрация: 04.05.2005
Возраст: 43

Yandex вне форума Не в сети
silly, его записи, не имеющие повторяющихся рост+год, вроде как не интересуют.
Если бы интересовали, то да - distinct подошел.
Если база известна, напр. MySQL или sqlite, которые позволяют выполнять "странные" запросы, вида
select id, value from t group by id
То запрос можно упростить.
  Ответить с цитированием
Старый 04.03.2012, 13:33   #17   
highly mean
 
Сообщений: 1,128
Регистрация: 26.05.2011
Возраст: 35

silly вне форума Не в сети
Пост №4.
  Ответить с цитированием
Старый 05.03.2012, 17:32   #18   
Форумец
 
Аватар для brk
 
Сообщений: 864
Регистрация: 07.04.2006

brk вне форума Не в сети
а я б индексное поле забабахал в котором данные по формуле age*1000+rost . Все эти вложенные селекты навевают скуку за бесцельно потраченные такты времени :-)
  Ответить с цитированием
Старый 06.03.2012, 00:15   #19   
highly mean
 
Сообщений: 1,128
Регистрация: 26.05.2011
Возраст: 35

silly вне форума Не в сети
Ммм… Вас успокоит, если я скажу, что после подобных манипуляций вложенность из приведенного Yandex'ом выражения не исчезнет, а в приведенном мной не появится?
  Ответить с цитированием
Поиск в теме: 



Быстрый переход:

  Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Support by DrIQ & Netwind