Dizinin bölümlerini ayıklamak için hızlı yolu?

5 Cevap php

Ben PHP büyük bir dizi var.

Bu çizgi kategorileri kullanarak bir tür ayrılır dizeleri içerir:

category1_property
category1_category2_category3
category2_category3_category4_category5

Ben adında bir işlevi var

array get_values($prefix)

Bu, örneğin, belirli bir öneki ile başlayan dizinin tüm değerleri döndürür

get_values("category2_category3_");

Bu fonksiyon foreach () yani basit, öneki ile başlayan tüm dizeleri toplama, tüm dizi boyunca her zaman es

foreach ($my_array as $line)
 if (substr($line, 0, strlen($prefix)) == $prefix)) 
  array_push ($result, $line);

Ben yapıyorum kötü hissediyorum performans-bilge, özellikle bu işlem istek başına onlarca kez gerçekleştirildiğini görüyoruz.

Herkes veri depolama bir bütün farklı bir şekilde başvurmak zorunda kalmadan bu hızlandırmak için bir yol biliyor mu?

Bir veritabanını kullanarak hızlı ve zeki olabilir ama ben o önlemek istiyorum. Veriler bir dosya geliyor ve ben bir veritabanına bağlantı bunu yapamam.

Ön ayırma veya çok-boyutlu bir diziye yapıyı bölme ya da bazen bir kategori adı parçaları sorgulamak gerekir, çünkü bir nesne, bir seçenek değildir (örn. "category1_ca *")

Herhangi bir giriş için şimdiden teşekkür ederiz.

5 Cevap

Zamanı verimli erişim için, ben basit çözüm dizi sıralama, ve binary search algorithm Sorgunuzla eşleşen alt ve üst dizi sınırlarını bulmak için değiştirilmiş bir varyantı kullanarak düşünüyorum. Benzer önek ile dizeleri her zaman sırayla sıralanır Bu çalışıyor çünkü.

Eğer bu dizi var sonra, uygun elemanları getiriliyor döngüsü için basit bir.

Açıkçası bu hiç önemsiz bir görevdir, bu yüzden bu really bir performans sorunu olmadığı sürece bu konuda herhangi bir zaman harcamayın. Prematüre optimizasyonu, sen matkap biliyorum ...

Sana preg_grep arıyorsanız düşünüyorum

Gerçekten seçenekleri sınırlıdır ettik! Buna rağmen, ben ön-bölme veri gitmek için yol olabilir düşünüyorum. Düşünün:

önekleri 'cat1_cat2_cat3_dog'='fido', 'cat1_cat2_cat3_fish'='goldie', 'cat1_cat2_cat3_frog'='kermit olur

$arr[cat1][cat2][cat3][dog]=fido
$arr[cat1][cat2][cat3][fish]=goldie
$arr[cat1][cat2][cat3][frog]=kermit

Eğer önek ile her şeyi istiyorsanız cat1_cat2:

$arr['cat1']['cat2']=array('cat3'=>array('dog'=>'fido','fish'=>'goldie'));

Eğer önek ile her şeyi istiyorsanız cat1_cat2_cat3_f* sen sadece son arama terimi gerek $arr['cat1']['cat2']['cat3']:

$matches=preg_grep("/^f/",array_keys($arr['cat1']['cat2']['cat3']));
foreach($matches as $k){
   $results[]=$arr['cat1']['cat2]['cat3'][$k];
}

Bu benim için açık ne get_values ​​fonksiyonu eşleşmesi gerekir - neyse, bu aradığınız performans dostu bir çözüm olabilir?

function get_values($prefix) {
	$included_array_from_file = array ( "category1_property", "category1_category2_category3", "category2_category3_category4_category5");

	foreach($included_array_from_file as $val) {
		if(strpos($val,$prefix)===0) {
			$out[] = $val;
		}
	}
	return $out;
}

print_r( get_values("category2_category3_") );

Output:
Array ( [0] => category2_category3_category4_category5 )

UPDATE:

Haklısınız, "category2_category3_" dizesinde kaç kez meydana saymak gerekiyor? Bu durumda, ben size tam dize için bir çok-boyutlu bir dizi oluşturmak ve bu örnekte görüldüğü gibi her geçtiği saymak öneririz: (örnek sadece nasıl yapılabilir göstermektedir Lütfen dikkat - Ben olduğum gibi örnek, şu anda başarısız Eğer diziye öğe eklerken başka bir "dizi oluşturmak" fonksiyonunu çağırmak gerekebilir anında çok boyutlu bir dizi oluşturmak için nasıl emin.) değil

Nasıl emin değil - ("bir dizi olarak bir skalar değeri kullanamazsınız") başarısız olur.

$data = array("category1_property", "category1_category2_category3", "category2_category3_category4_category5");
$counter = array();
foreach($data as $val) {
	foreach(explode(":",$val) as $val2) {
		// Now, create a multi-dimensional array with the category items as keys and increment the value by one for each item in the string, as in this example:
		// "category2_category3_category4_category5" ... turns into:
		// $counter[category2] += 1;
		// $counter[category2][category3] += 1;
		// $counter[category2][category3][category4] += 1;
		// $counter[category2][category3][category4][category5] += 1;
	}
}

Amaçlanan kullanımı:

echo $counter[category2][category3];

Yoksa array_filter ile bir anonim işlevini kullanabilirsiniz ():

function get_values($arr, $str)
{
    $func = create_function('$item', 'return (strpos($item, "' . $str . '") === 0);');
    return array_filter($arr, $func);
}

$prefix = 'category1';
$result = get_values($my_array, $prefix);