Алгоритм генерации SKU Есть решение

Где найти саму генерацию SKU для продукта по выбираемым характеристикам?

интересует создание уникальных значений путем слияния всех характерстик, чтобы не было повторных значений и разном порядке.

Или если есть у кого похожий алгоритм , напишите.

пример: есть массив из трех характеристик

<?php
 $features = array(
            '30' => array(
                130,140,160
            ),
            '78' => array(
                250,280,290
            ),
            '90' => array(
                300,320,340
            ),
        );

Надо на выходе получить массив

<?php


        $skus = array(
            '130,250,300',
            '130,250,320',
            '130,270,300',
            '130,270,320',
            '140,250,300',
            '140,250,320',
            '140,270,300',
            '140,270,320',
        );

3 ответа

  • 3

    Сделал в таком виде:

    <?php
     class generateProductSkus {
         protected $features = array();
         protected $skus = array();
         public function __construct() {
    
         }
         public function getSkus($features) {
             if(!empty($features)) {
                 $this->generateSkuVariants($features);
             }
             return $this->skus;
    
         }
         protected function  generateSkuVariants($features, $features_values = array(), $level = 0)
         {
             foreach ($features as $k => $values) {
                 $features_temp = $features;
                 unset($features_temp[$k]);
                 foreach ($values as $value) {
                     $features_values[$k] = $value;
                     if(count($features_temp) > 0) {
                         $this->generateSkuVariants($features_temp, $features_values, $level++);
                     } else {
                         $str_sku = '';
                         foreach ($features_values as $features_values_feature_id => $features_values_feature_value_id) {
                             $str_sku .= $features_values_feature_id.':'.$features_values_feature_value_id.';';
                         }
                         $this->skus[$str_sku] =  $features_values;
                     }
                 }
             }
         }
     }
    
    
    $features = array(
        '10' => array(
            110,120,130
        ),
        '20' => array(
            210,220,230
        ),
        '30' => array(
            310,320,330
        ),
        '40' => array(
            410,420,430
        ),
    );
    $generator = new generateProductSkus();
    $skus = $generator->getSkus($features);
    var_dump($skus);
  • 1

    Писал на js что-то подобное, но сам уже не помню как работает)


    $.findSku = {
        form:{},
        features:{},
        sku_variants:{},
        features_values_variants:{},
        no_hide_feature_values: {28:true},
    
        // settings
        feature_selector: '.sku-feature',
        feature_element_data_id: 'feature-id',
    
        init: function(form, sku_features){
            this.form = form;
            this.features = sku_features;
            this.features_values_variants = this.getFeaturesValuesVariants();
            this.sku_variants = {};
        },
        find: function (feature_obj) {
            var self = this;
            var   key_arr = [];
            self.form.find(''+this.feature_selector+'').each(function () {
                var feature_id = $(this).data(''+self.feature_element_data_id+'');
                key_arr[feature_id] = feature_id + ':' + $(this).val() + ';';
            });
            var variants = self.getSkuVariants(key_arr);
            var sku = false;
            for (var k in variants) {
                if( typeof(self.features[variants[k]]) == 'object' ) {
                    sku = self.features[variants[k]];
                }
            }
            self.setSkuFeaturesValues($(feature_obj));
            if(!sku) {
                sku = self.findSku($(feature_obj));
            }
            return sku;
        },
        findSku :function(changed_feature_obj) {
            var self = this;
            var value_id = $(changed_feature_obj).val();
            var feature_id = $(changed_feature_obj).data('feature-id');
            var form =   this.form;
            var features = this.features_values_variants[value_id];
    
            var variants = {};
            for(var k in features) {
                for(var fk in features[k]) {
                    for(var sku_d in features[k][fk]) {
                        if(typeof (variants[sku_d])!='object') {
                            variants[sku_d] ={};
                        }
                        variants[sku_d][k] = fk;
                    }
    
                }
            }
            var max_count_features = 0;
            var max_count_identical = 0;
            var count_sku_features = {};
            for(var vk in variants) {
                var variant = variants[vk];
                var count_identical = 0;
                self.form.find(''+this.feature_selector+'').each(function () {
                    var feature_id = $(this).data(''+self.feature_element_data_id+'');
                    if(typeof (variant[feature_id])!=='undefined') {
                        if(variant[feature_id]==$(this).val()) {
                            count_identical++;
                        }
                    }
                });
                var count_features = this.count(variant);
                if(count_features >= max_count_features && count_identical>=max_count_identical) {
                    max_count_features = count_features;
                    max_count_identical = count_identical;
                }
                count_sku_features[vk] = {};
                count_sku_features[vk]['count'] = count_features;
                count_sku_features[vk]['count_identical'] = count_identical;
            }
            var sku_key = false;
            for(var ck in count_sku_features) {
                if(count_sku_features[ck]['count'] == max_count_features && count_sku_features[ck]['count_identical'] == max_count_identical ) {
                    for(var vfk in variants[ck]) {
                        $('[name="features['+vfk+']"]').val(variants[ck][vfk]);
                    }
                    sku_key = ck;
                    break;
                }
            }
            var sku = false;
            if(sku_key) {
                var   key_arr = [];
                self.form.find(".sku-feature").each(function () {
                    key_arr[$(this).data('feature-id')] = $(this).data('feature-id') + ':' + $(this).val() + ';';
                });
                var sku_variants = self.getSkuVariants(key_arr);
                var sku = false;
                for (var k in sku_variants) {
                    if( typeof(self.features[sku_variants[k]]) == 'object' ) {
                        sku = self.features[sku_variants[k]];
                    }
                }
            }
            return sku;
        },
    
        getSkuVariants: function(arr) {
            this.sku_variants = {};
            this.generateSkuVariants(arr);
            return this.sku_variants;
        },
        generateSkuVariants: function(arr, temp ,level) {
            if(typeof (level)!='number') {
                var level = 0; // если нет уровня вложенности рекурсии
            }
            for (var k in arr) {
                if(level<1) {
                    var temp = '';// очищаем для первых символов
                }
                var arr1 = arr.slice();
                delete arr1[k];// удаляем символ чтобы избежать повторения
                // если еще есть символы
                if(count(arr1)>0) {
                    this.generateSkuVariants(arr1, temp+''+arr[k],level+1);
                } else {
                    this.sku_variants[temp+''+arr[k]]=temp+''+arr[k];
                }
            }
        },
        setSkuFeaturesValues : function(changed_feature_obj){
            var value_id = changed_feature_obj.val();
            var feature_id = changed_feature_obj.data('feature-id');
            var form =   changed_feature_obj.closest('form');
            if(typeof (this.features_values_variants[value_id])=='object') {
                var features = this.features_values_variants[value_id];
                for(k in features) {
                    if(!this.no_hide_feature_values[k]) {
                        var feature_obj =  form.find('[name="features['+k+']"]');
                        feature_obj.find('option').hide();
                        for(fv in features[k]) {
                            feature_obj.find('option[value="'+fv+'"]').show();
                        }
                    }
                }
            }
        },
    
    
        //////////////////////////////////////////////////
        getFeaturesValuesVariants: function(){
            var features_values_variants = {};
    
            for(sku_id in this.features) {
                var features = this.getSkuKeyFeaturesValues(sku_id);
                for(var feature_id in features) {
                    var feature_value = features[feature_id];
                    if(typeof (features_values_variants[feature_value])!=='object') {
                        features_values_variants[feature_value] = {};
                    }
                    for(var feature_val_id in features) {
                        if(feature_id!==feature_val_id) {
                            var  feature_val_value = features[feature_val_id];
                            if(typeof (features_values_variants[feature_value][feature_val_id]) !='object') {
                                features_values_variants[feature_value][feature_val_id] = {};
                            }
                            if(typeof ( features_values_variants[feature_value][feature_val_id][feature_val_value]) !='object') {
                                features_values_variants[feature_value][feature_val_id][feature_val_value] = {};
                            }
                            features_values_variants[feature_value][feature_val_id][feature_val_value][sku_id] = sku_id;
                        }
                    }
                }
            }
            return features_values_variants;
        },
        getSkuKeyFeaturesValues: function(sku_key){
            var features = sku_key.split(';');
            var return_features = {};
            for(fk in features) {
                if(features[fk]!='') {
                    var feature_arr = features[fk].split(':');
                    var feature_id = feature_arr[0];
                    var feature_value = feature_arr[1];
                    return_features[feature_id] = feature_value;
                }
            }
            return return_features;
    
        },
    
        count: function( mixed_var, mode ) {
            var key, cnt = 0;
            if( mode == 'COUNT_RECURSIVE' ) mode = 1;
            if( mode != 1 ) mode = 0;
            for (key in mixed_var){
                cnt++;
                if( mode==1 && mixed_var[key] && (mixed_var[key].constructor === Array || mixed_var[key].constructor === Object) ){
                    cnt += count(mixed_var[key], 1);
                }
            }
            return cnt;
        }
    };


  • 1

    Вот такой массив должен получиться и каждая последняя по вложенности ячека это уникальный SKU


    <?php
    
    $features = array(
        '10' => array(
            110,120,130
        ),
        '20' => array(
            210,220,230
        ),
        '30' => array(
            310,320,330
        ),
        '40' => array(
            410,420,430
        ),
    );
    $values = array(
        110 =>[
            210 =>[
                310 =>[
                    410=> array(110,210,310,410),
                    420=> array(110,210,310,420),
                    430=> array(110,210,310,430),
                ],
                320 =>[
                    410=> array(110,210,320,410),
                    420=> array(110,210,320,420),
                    430=> array(110,210,320,430),
                ],
                330 =>[
                    410=> array(110,210,330,410),
                    420=> array(110,210,330,420),
                    430=> array(110,210,330,430),
                ],
            ],
            220 =>[
                310 =>[
                    410=> array(110,220,310,410),
                    420=> array(110,220,310,420),
                    430=> array(110,220,310,430),
                ],
                320 =>[
                    410=> array(110,220,320,410),
                    420=> array(110,220,320,420),
                    430=> array(110,220,320,430),
                ],
                330 =>[
                    410=> array(110,220,330,410),
                    420=> array(110,220,330,420),
                    430=> array(110,220,330,430),
                ],
            ],
            230 =>[
                310 =>[
                    410=> array(110,230,310,410),
                    420=> array(110,230,310,420),
                    430=> array(110,230,310,430),
                ],
                320 =>[
                    410=> array(110,230,320,410),
                    420=> array(110,230,320,420),
                    430=> array(110,230,320,430),
                ],
                330 =>[
                    410=> array(110,230,330,410),
                    420=> array(110,230,330,420),
                    430=> array(110,230,330,430),
                ],
            ],
            ],
        120  =>[
            210 =>[
                310 =>[
                    410=> array(120,210,310,410),
                    420=> array(120,210,310,420),
                    430=> array(120,210,310,430),
                ],
                320 =>[
                    410=> array(120,210,320,410),
                    420=> array(120,210,320,420),
                    430=> array(120,210,320,430),
                ],
                330 =>[
                    410=> array(120,210,330,410),
                    420=> array(120,210,330,420),
                    430=> array(120,210,330,430),
                ],
            ],
            220 =>[
                310 =>[
                    410=> array(120,220,310,410),
                    420=> array(120,220,310,420),
                    430=> array(120,220,310,430),
                ],
                320 =>[
                    410=> array(120,220,320,410),
                    420=> array(120,220,320,420),
                    430=> array(120,220,320,430),
                ],
                330 =>[
                    410=> array(120,220,330,410),
                    420=> array(120,220,330,420),
                    430=> array(120,220,330,430),
                ],
            ],
            230 =>[
                310 =>[
                    410=> array(120,230,310,410),
                    420=> array(120,230,310,420),
                    430=> array(120,230,310,430),
                ],
                320 =>[
                    410=> array(120,230,320,410),
                    420=> array(120,230,320,420),
                    430=> array(120,230,320,430),
                ],
                330 =>[
                    410=> array(120,230,330,410),
                    420=> array(120,230,330,420),
                    430=> array(120,230,330,430),
                ],
            ],
        ],
        130 =>[
            210 =>[
                310 =>[
                    410=> array(130,210,310,410),
                    420=> array(130,210,310,420),
                    430=> array(130,210,310,430),
                ],
                320 =>[
                    410=> array(130,210,320,410),
                    420=> array(130,210,320,420),
                    430=> array(130,210,320,430),
                ],
                330 =>[
                    410=> array(130,210,330,410),
                    420=> array(130,210,330,420),
                    430=> array(130,210,330,430),
                ],
            ],
            220 =>[
                310 =>[
                    410=> array(130,220,310,410),
                    420=> array(130,220,310,420),
                    430=> array(130,220,310,430),
                ],
                320 =>[
                    410=> array(130,220,320,410),
                    420=> array(130,220,320,420),
                    430=> array(130,220,320,430),
                ],
                330 =>[
                    410=> array(130,220,330,410),
                    420=> array(130,220,330,420),
                    430=> array(130,220,330,430),
                ],
            ],
            230 =>[
                310 =>[
                    410=> array(130,230,310,410),
                    420=> array(130,230,310,420),
                    430=> array(130,230,310,430),
                ],
                320 =>[
                    410=> array(130,230,320,410),
                    420=> array(130,230,320,420),
                    430=> array(130,230,320,430),
                ],
                330 =>[
                    410=> array(130,230,330,410),
                    420=> array(130,230,330,420),
                    430=> array(130,230,330,430),
                ],
            ],
        ],
    //// Тут нет смысла перебирать, уже есть со всеми вариантами
        210,
        220,
        230,
    
        310,
        320,
        330,
    
        410,
        420,
        430
    
    
    );

Добавить ответ

Чтобы добавить комментарий, зарегистрируйтесь или войдите