要素を最後に追加するこのメソッドと同様に、最初の要素としてコレクションに要素を追加することは可能ですか?
$product = Mage::getModel('catalog/product')->load(15879);
$productCollection->addItem($product);
要素を最後に追加するこのメソッドと同様に、最初の要素としてコレクションに要素を追加することは可能ですか?
$product = Mage::getModel('catalog/product')->load(15879);
$productCollection->addItem($product);
回答:
免責事項:可能な限り、並べ替えの目的でデータベースを使用してください。ただし、場合によっては、データベースに格納されていないコレクションのアイテムを(まだ)整理する必要があります
collectTotals()
。たとえば、中にアイテムを見積もりに動的に追加した後などです。次に、このアプローチが役立ちます。
残念ながらVarien_Data_Collection
、この点では非常に柔軟ではありません。コレクション内のアイテムを並べ替えるには、アイテムを削除して、目的の順序で再度追加する必要があります。
あなたの特定のケースでは:
// remove previous items, keep them in $items
$items = $productCollection->getItems();
foreach ($productCollection as $key => $item) {
$collection->removeItemByKey($key);
}
// add new item
$productCollection->addItem($product);
// re-add $items
foreach ($items as $item) {
$productCollection->addItem($item);
}
パフォーマンスに異論があるため、実際の製品データベースで少しベンチマークを行いました。20Kの製品でコレクションをロードすることは絶対にしてはいけないことですが、これはロードされた配列を2回繰り返しても重要なオーバーヘッドが追加されないことを証明するためです。
テストスクリプト
$startTime = microtime(true);
$productCollection = Mage::getResourceModel('catalog/product_collection')->load();
printf("Loaded %d products. Time: %.2fs Memory: %s\n",
$productCollection->count(), microtime(true)-$startTime, number_format(memory_get_usage(true)));
// remove previous items, keep them in $items
$items = $productCollection->getItems();
foreach ($productCollection as $key => $item) {
$productCollection->removeItemByKey($key);
}
printf("Removed items. Time %.2fs Memory: %s\n",
microtime(true)-$startTime, number_format(memory_get_usage(true)));
// add new item
$productCollection->addItem(Mage::getModel('catalog/product'));
// re-add $items
foreach ($items as $item) {
$productCollection->addItem($item);
}
printf("Added items. Time %.2fs Memory: %s\n",
microtime(true)-$startTime, number_format(memory_get_usage(true)));
出力
20761製品をロードしました。時間:3.70秒メモリ:81,264,640
削除されたアイテム。時間3.92メモリ:81,788,928
追加されたアイテム。時間4.31メモリ:81,788,928
そして、より現実的な量の100個のロードされた製品で:
100個の商品を読み込みました。時間:0.11秒メモリ:10,223,616
削除されたアイテム。時間0.11秒メモリ:10,223,616
追加されたアイテム。時間0.12秒メモリ:11,272,192
コレクションオブジェクトには_items
、データベースクエリによって取得されたすべての結果モデルを含む、という標準配列があります。addItem()
メソッドは、クラス内に存在Varien_Data_Collection
し、あなたはそれをすべてを見れば、それは配列の最後にエントリをプッシュしているし、全く同じ動作が適用されないarray_push:
public function addItem(Varien_Object $item)
{
$itemId = $this->_getItemId($item);
if (!is_null($itemId)) {
if (isset($this->_items[$itemId])) {
throw new Exception('Item ('.get_class($item).') with the same id "'.$item->getId().'" already exist');
}
$this->_items[$itemId] = $item;
} else {
$this->_addItem($item);
}
return $this;
}
そして、_addItem()
方法は次のとおりです:
protected function _addItem($item)
{
$this->_items[] = $item;
return $this;
}
したがって、addItem()
メソッドを呼び出すときに発生するのは、キーとして存在する場合は追加する項目のIDを使用して新しいエントリが配列の最後に追加され、それ以外の場合は次に利用可能な自動インクリメントキー値を使用することです(定義しないことにより)かぎ)。
アイテムを特定の方法でgetItems()
並べ替える必要がある場合は、代わりにデータベースクエリが結果を正しく並べ替えるか、コレクションオブジェクトからすべてのアイテムをプルしてからPHPを使用して並べ替える必要があります。FARによる最も効率的な方法は、データベースクエリでそれらを正しく順序付けることです。PHPを介してデータベースから取得した結果の操作は、数え切れないほど時間がかかります。
私は適切な解決策を手に入れます。
新しいバリアンコレクションオブジェクトを作成します。
$collection- = new Varien_Data_Collection();
$product = Mage::getModel('catalog/product')->load(15879);
product add first elementを割り当てます。
$collection->addItem($product);
残りの製品のループ割り当てを使用する:
foreach($productCollection as $eachProd):
$collection->addItem($eachProd);
endforeach;
$productCollection=$collection;
getFirstItem()
最初の要素としてコレクションに要素を追加するのと同じタスクがありました。以下は、私が実装したコードで、完全に機能します。
$product = Mage::Model('catalog/product')->load(product_id);// product/element to add as first element
$collection = Mage::Model('catalog/product')->getCollection();
$collection->addAttributeToSelect.... // general code to select attributes
$collection->addAttributeToFilter.... // general code to apply filter
if($product && $product->getId()){ **// product to add as first element**
$collection->addItem($product); // added product to collection
$expr = new Zend_Db_Expr("`e`.`entity_id` = {$product->getId()} desc");
$collection->getSelect()->order($expr); **// $product will be order by DESC to set as first element**
}
$collection->addAttributeToSort( 'price', 'asc'); // this sorting will apply on remaining elements in the collection.
上記のコードで$product
は、最初の要素として追加する必要があり$collection
、$product
そのコレクションに追加された製品コレクションを作成しました。
の$collection->getSelect()->order($expr);
強制ソート位置を使用して$product
、最初の位置として設定し、残りの要素を次の順序で並べます。$collection->addAttributeToSort( 'price', 'asc');
注 - $collection->getSelect()->order($expr);
コードによる並べ替えの前に呼び出す必要があります。