在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問(wèn)答/HTML5  HTML/ 關(guān)于多維數(shù)組排列組合的問(wèn)題

關(guān)于多維數(shù)組排列組合的問(wèn)題

最近遇到了一個(gè)關(guān)于商品屬性求組合的問(wèn)題,怕我描述不好先上圖:如下

圖片描述

1、旁邊的顏色尺碼什么的 數(shù)量都是不確定的(因?yàn)橛锌赡苁羌译姡称罚蛘叻b什么的)
2、右邊的屬性值是允許手動(dòng)添加的,所以數(shù)量也是不確定的

為了規(guī)范庫(kù)存啥的,所以要分別排列組合出各種規(guī)格的商品并添加庫(kù)存,我現(xiàn)在手動(dòng)取到了上面的值格式如下:

data = {
    color:[value1,value2,value3,....],
    size:[value1,value2,value3,....],
    style:[value1,value2,value3,....]
}

然后我就不知道怎么求組合了,我主要是不知道如何遞歸,如何創(chuàng)建中間變量,求各位大佬給點(diǎn)思路,或者給出你們的代碼讓我參考一下,有注釋更好,感謝!?。?!深夜加班,我要哭了

回答
編輯回答
心沉

湊個(gè)熱鬧。。。

這個(gè)數(shù)據(jù)結(jié)構(gòu)只有兩層,只是每一層的數(shù)量不確定。所以?xún)蓪友h(huán)就夠了,沒(méi)有必要遞歸。

var data = {
  color: ['color1', 'color2', 'color3'],
  size: ['size1', 'size2', 'size3'],
  style: ['style1', 'style2', 'style3']
}

Object.values(data).reduce( (result, property) => {
    return property.reduce( (acc, value) => {
        return acc.concat(result.map( ele => [].concat(ele, value)));
    }, []);
});

輸出結(jié)果為包含對(duì)象的數(shù)組:

// 循環(huán)每一個(gè)商品屬性
Object.keys(data).reduce( (result, key) => {

        // 循環(huán)屬性的每一個(gè)值
        return data[key].reduce( (acc, value) => {

            // 對(duì)于第一個(gè)屬性
            if (!result.length) {
                // 將數(shù)值轉(zhuǎn)化為對(duì)象格式
                return acc.concat({ [key]: value });
            }

            // 對(duì)于第一個(gè)之后的屬性,將新的屬性和值添加到已有結(jié)果,并進(jìn)行拼接。
            return acc.concat( result.map( ele => (Object.assign({}, ele, { [key]: value }) )));
        }, []);
    }, []);
2017年2月19日 03:57
編輯回答
青瓷

總結(jié)了幾位大神的答案,我自己提出了一個(gè)新的需求,我想最終的數(shù)據(jù)格式是一個(gè)成員為對(duì)象的數(shù)組,對(duì)象包含的屬性就是我要使用的值,所以我消化了一下擼出了下面這段:

        var data = {
            size: ['size1', 'size2', 'size3'],
            color: ['color1', 'color2', 'color3'],
            style: ['style1', 'style2', 'style3']
        };

        var pr = (function(data){
            var aa = [];
            for(var pro in data){
                aa.push(pro);
            }
            return aa;
        })(data);
        Object.values(data).reduce(function(objs,props,index){
            debugger
            if(objs.length==0){
                return props.reduce(function(oo,att){
                    var oob = new Object();
                    oob[pr[index]] = att;
                    return oo.concat(oob);
                },[]);
            }else{
                var item = objs.reduce(function(ritem,oo){
                    var tt = props.reduce(function(subitem,att){
                        var oob = new Object();
                        for(var i in oo){
                            oob[i] = oo[i];
                        }
                        oob[pr[index]] = att;
                        subitem.push(oob);
                        return subitem;
                    },[]);
                    return ritem.concat(tt)
                },[]);
                return item;
            }
            
        },[])
2017年9月21日 09:55
編輯回答
維他命

熬夜加班不容易呀,我搜了下資料,結(jié)合別人的例子,自己寫(xiě)了個(gè)
你可以參考一下。
主要思路是遞歸組合前兩個(gè)

function handleCombine(arr) {
  debugger
  var len = arr.length;
  if (len >= 2) {
    //從前兩個(gè)開(kāi)始組合
    var len1 = arr[0].length;
    var len2 = arr[1].length;
    var lenBoth = len1 * len2;
    var items = new Array(lenBoth);
    var index = 0;
    //for循環(huán)構(gòu)建兩兩組合后的數(shù)組
    for (var i = 0; i < len1; i++) {
      for (var j = 0; j < len2; j++) {
        if (arr[0][i] instanceof Array) {
          items[index] = arr[0][i].concat(arr[1][j]);
        } else {
          items[index] = [arr[0][i]].concat(arr[1][j]);
        }
        index++;
      }
    }
    // 新組合的數(shù)組取代原來(lái)前兩個(gè)數(shù)組
    var newArr = new Array(len - 1);
    for (var i = 2; i < arr.length; i++) {
      newArr[i - 1] = arr[i];
    }
    newArr[0] = items;
    // 再次組合前兩個(gè)
    return handleCombine(newArr);
  } else {
    return arr[0];
  }
}

var data = {
  color: ['color1', 'color2', 'color3'],
  size: ['size1', 'size2', 'size3'],
  style: ['style1', 'style2', 'style3']
}

var multiArr = []
for (key in data) {
  multiArr.push(data[key])
}

console.log(handleCombine(multiArr));
2018年8月14日 09:03
編輯回答
氕氘氚

這個(gè)問(wèn)題按照常規(guī),全排列的前提是知道對(duì)象里面的所有屬性,然后利用多種for循環(huán)或者簡(jiǎn)便的forEach語(yǔ)句進(jìn)行一一配對(duì)

樓上已經(jīng)把解決方案都列出來(lái)了,我這里說(shuō)一下我的思考。

我在想能不能封裝一個(gè)方法,能夠自動(dòng)遍歷給定對(duì)象的所有屬性所對(duì)應(yīng)的值,然后將它們進(jìn)行全排列。這樣就不需要預(yù)先知道對(duì)象的所有key,只要保證它的結(jié)構(gòu)符合我們的要求即可。

這里要求的對(duì)象結(jié)構(gòu)是:

var data = {
    key1: [val1, val2, ...],
    key2: [val1, val2, ..],
    key3: [val1, val2, ..],
    ...
};

經(jīng)過(guò)實(shí)踐,我封裝出來(lái)了一個(gè)generatePropertyValueArrange(obj)方法,只要保證這個(gè)obj這個(gè)對(duì)象的結(jié)構(gòu)符合我們的要求,就能夠保證輸出正確的所有對(duì)應(yīng)屬性值的數(shù)組的全排列組合。

思路如下:

  1. 先構(gòu)造出對(duì)象的所有屬性所對(duì)應(yīng)值的數(shù)組遍歷的forEach語(yǔ)句,類(lèi)似以下的語(yǔ)句,即

       obj.key1.forEach(key1 => {
         obj.key2.forEach(key2 => {
         ...
         });
       });
  2. 然后使用eval來(lái)執(zhí)行剛剛生成的forEach語(yǔ)句,這里有點(diǎn)像模板引擎的味道

完整代碼如下:

// 構(gòu)建符合要求的對(duì)象
var data = {
  color: ['red', 'blue', 'black'],
  size: ['S', 'M', 'L'],
  style: ['child', 'young', 'middle'],
  height: ['short', 'high'],
  // 這里可以添加形如key: [..., ...] 這種形式的項(xiàng)
};

// 調(diào)用構(gòu)造方法
var dataArrange = generatePropertyValueArrange(data);

// 輸出結(jié)果
console.log(dataArrange);

/*
* 生成對(duì)象的屬性值的全排列
* @return array
* */
function generatePropertyValueArrange(obj) {
  var objKeys = Object.keys(obj);
  var length = objKeys.length;
  var statementChain = ''; // forEach的語(yǔ)句
  var num = 0; // 記錄obj的key值遍歷的位置,比如color為0,size為1
  var result = []; // 執(zhí)行結(jié)果存放的數(shù)組

  getObjForEachStatement(); // 執(zhí)行獲取對(duì)象的forEach執(zhí)行語(yǔ)句
  console.log(statementChain); // 打印以下執(zhí)行語(yǔ)句
  eval(statementChain); // 執(zhí)行生成的forEach語(yǔ)句

  // 返回result
  return result;

  /*
  * 具體生成執(zhí)行語(yǔ)句的函數(shù),主要通過(guò)修改statementChain,num和result
  * */
  function getObjForEachStatement() {
    var key = objKeys[num];

    // 比如生成:obj['color'].forEach( color => {
    statementChain += "obj['"+ key +"'].forEach( "+ key +" => {\n";

    // 如果已經(jīng)是遍歷到最后一個(gè)屬性,那么push結(jié)果
    if (num === length - 1) {
      // 比如生成:color:color,size:size,style:style,height:height,
      // 屬性名稱(chēng):屬性值的形式
      var item =  objKeys.reduce((acc, curr) => {
        return acc.concat([curr, ':', curr].join('')).concat(',');
      }, '');

      // 添加到forEach語(yǔ)句中
      // "});".repeat(length);的作用是封閉forEach語(yǔ)句
      statementChain += "result.push({\n\t"+ item +"\n});" + "});".repeat(length);
    }

    num++;

    if (num < length) {
      // 屬性還沒(méi)有遍歷完,遞歸
      getObjForEachStatement();
    }
  }
}

測(cè)試結(jié)果如下:

// 生成的forEach語(yǔ)句
obj['color'].forEach( color => {
obj['size'].forEach( size => {
obj['style'].forEach( style => {
obj['height'].forEach( height => {
result.push({
    color:color,size:size,style:style,height:height,
});});});});});

// 構(gòu)造的全排列數(shù)組
[ { color: 'red', size: 'S', style: 'child', height: 'short' },
  { color: 'red', size: 'S', style: 'child', height: 'high' },
  { color: 'red', size: 'S', style: 'young', height: 'short' },
  { color: 'red', size: 'S', style: 'young', height: 'high' },
  { color: 'red', size: 'S', style: 'middle', height: 'short' },
  { color: 'red', size: 'S', style: 'middle', height: 'high' },
  { color: 'red', size: 'M', style: 'child', height: 'short' },
  { color: 'red', size: 'M', style: 'child', height: 'high' },
  { color: 'red', size: 'M', style: 'young', height: 'short' },
  { color: 'red', size: 'M', style: 'young', height: 'high' },
  { color: 'red', size: 'M', style: 'middle', height: 'short' },
  { color: 'red', size: 'M', style: 'middle', height: 'high' },
  { color: 'red', size: 'L', style: 'child', height: 'short' },
  ......

大概就這些。

2017年1月22日 22:59
編輯回答
兔囡囡
let color = ['blue','red','white'];
let size = ['s','m','l'];
let style = [1,2,3];
let result = [];
for (var i = 0; i < color.length; i++) {
    for (var j = 0; j < size.length; j++) {
        for (var k = 0; k < style.length; k++) {
            result.push({
                color: color[i],
                size: size[j],
                style: style[k]
            })
        }        
    }    
}
console.log(result);
2018年2月16日 22:47