js笛卡尔积算法汇总

1,什么是笛卡尔乘积?
笛卡尔乘积是指在数学中,两个集合_X_和_Y_的笛卡尔积(Cartesian product),又称直积,表示为_X_×_Y_,第一个对象是_X_的成员而第二个对象是_Y_的所有可能有序对的其中一个成员-----百度定义

2,什么时候用笛卡尔积?
假设有俩个输入框,框1输入1,2俩个数,框2输入a,b,c三个参数,接口入参格式要{[1,a],[1,b],[1,c],[2,a],[2,b],[2,c]}这样的组合时,就可以用笛卡尔积函数
3,笛卡尔积函数
(1)如2中参数格式可用

function descartes(list) {
  //parent上一级索引;count指针计数
  var point = {};
  var result = [];
  var pIndex = null;
  var tempCount = 0;
  var temp = [];
  //根据参数列生成指针对象
  for (var index in list) {
    if (typeof list[index] == 'object') {
      point[index] = { 'parent': pIndex, 'count': 0 }
      pIndex = index;
    }
  }
  //单维度数据结构直接返回
  if (pIndex == null) {
    return list;
  }
  //动态生成笛卡尔积
  while (true) {
    for (var index in list) {
      tempCount = point[index]['count'];
      temp.push(list[index][tempCount]);
    }
    //压入结果数组
    result.push(temp);
    temp = [];
    //检查指针最大值问题
    while (true) {
      if (point[index]['count'] + 1 >= list[index].length) {
        point[index]['count'] = 0;
        pIndex = point[index]['parent'];
        if (pIndex == null) {
          return result;
        }
        //赋值parent进行再次检查
        index = pIndex;
      }
      else {
        point[index]['count']++;
        break;
      }
    }
  }
}
调用方式:
var result = descartes({'aa':['a1','a2'],'bb':['b1','b2'],'cc':['c1','c2']});
console.log(result);//result就是笛卡尔积
此时result=[["a1","b1","c1"],["a1","b1","c2"],["a1", "b2", "c1"],["a1", "b2", "c2"],["a2", "b1", "c1"],["a2", "b1", "c2"],["a2", "b2", "c1"],["a2", "b2", "c2"]]

(2)简单实现笛卡尔积

function cartesianProductOf() {
    return Array.prototype.reduce.call(arguments,       function(a, b) {
    var ret = [];
        a.forEach(function(a) {
        b.forEach(function(b) {
        ret.push(a.concat([b]));
      });
    });
   return ret;
  }, [[]]);
}

调用方式:

let result =cartesianProductOf(['1','2','3'],['a','b'])
  console.log(result)
此时result=[["a1","b1","c1"],["a1","b1","c2"],["a1", "b2", "c1"],["a1", "b2", "c2"],["a2", "b1", "c1"],["a2", "b1", "c2"],["a2", "b2", "c1"],["a2", "b2", "c2"]]

(3)上述俩种方法的传参格式虽然不同,但得到的结果都是标准数组形式,如果想要对象数组的传参格式,需要对(1)函数稍加修改

function descartes(list) {
  //parent上一级索引;count指针计数
  var point = {};
  var result = [];
  var pIndex = null;
  var tempCount = 0;
  let obj = {};
  //根据参数列生成指针对象
  for (var index in list) {
    if (typeof list[index] === 'object') {
      point[index] = {
        'parent': pIndex,
        'count': 0
      }
      pIndex = index;
    }
  }
  //单维度数据结构直接返回
  if (pIndex === null) {
    return list;
  }
  //动态生成笛卡尔积
  while (true) {
    for (var index in list) {
      tempCount = point[index]['count'];
      obj[index] = list[index][tempCount]   ----区别
    }
    //压入结果数组
    result.push(obj);
    obj={};   -----区别
    //检查指针最大值问题
    while (true) {
      if (point[index]['count'] + 1 >= list[index].length) {
        point[index]['count'] = 0;
        pIndex = point[index]['parent'];
        if (pIndex === null) {
          return result;
        }
        //赋值parent进行再次检查
        index = pIndex;
      } else {
        point[index]['count']++;
        break;
      }
    }
  }
}

调用方式:

var result = descartes({'aa':['a1','a2'],'bb':['b1','b2'],'cc':['c1','c2']});
console.log(result);//result就是笛卡尔积
此时result=[{aa: "a1", bb: "b1", cc: "c1"},{aa: "a1", bb: "b1", cc: "c2"},{aa: "a1", bb: "b2", cc: "c1"},{aa: "a1", bb: "b2", cc: "c2"},{aa: "a2", bb: "b1", cc: "c1"},{aa: "a2", bb: "b1", cc: "c2"},{aa: "a2", bb: "b2", cc: "c1"},{aa: "a2", bb: "b2", cc: "c2"}]

这三种函数的主要区别在于:result的格式,注意传参要求即可。

你可能感兴趣的:(前端,javascript)