JavaScript中的SUM-IFS

JavaScript中的SUM-IFS,javascript,Javascript,如何基于多个真条件的一致性实现求和逻辑,即: 我有一个输入数组: 价值:[[dec','toy',12/4/2020,50],'dec','pen',14/4/2020,50],'dec','toy',14/4/2020,53],'dec','toy',4/4/2020,50],] 标题:['month'、'object'、'day'、'score'] 现在我有了一个函数,它包含4个参数: 标题数组 值数组 条件字符串 函数sumif(summationMetricHeader、header、v

如何基于多个真条件的一致性实现求和逻辑,即:

我有一个输入数组:

价值:
[[dec','toy',12/4/2020,50],'dec','pen',14/4/2020,50],'dec','toy',14/4/2020,53],'dec','toy',4/4/2020,50],]

标题:
['month'、'object'、'day'、'score']

现在我有了一个函数,它包含4个参数:

  • 标题数组
  • 值数组
  • 条件字符串
  • 函数sumif(summationMetricHeader、header、value、condition)

    其中,
    条件
    字符串如下:
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    其中@@是指定4个比较参数的分隔符,是多个条件之间的分隔符

    如果所有条件均为真,则应添加
    总和水头

    例如:

    价值:
    [[dec','toy',12/4/2020,50],'dec','pen',14/4/2020,50],'dec','toy',14/4/2020,53],'dec','toy',4/4/2020,50],]

    标题:
    ['month'、'object'、'day'、'score']

    总和指标:
    得分

    条件字符串:
    12/4/2020@>=@@Date@@day,50@>=@@Number@@score

    现在,只有当day列大于等于2020年12月4日时,这里才显示sum(比较必须是指定的日期比较),并且当score大于等于50时(这里的比较是数字类型)

    因此,输出将为:50+50+53(对于values数组中的最后一个元素,day列的值小于指定的条件)

    总共有三种比较:

    let decision = true;
    if(stringElem.split("@@")[2] === 'Date')
            decision = decision && eval(`${new Date(stringElem.split("@@")[0]).getTime()}${stringElem.split("@@")[1]}${new Date(value[i]).getTime()}`)
    
    
    else if(stringElem.split("@@")[2] === 'String')
            decision = decision && eval(`'${stringElem.split("@@")[0]}'${stringElem.split("@@)[1]}'${value[i]}'`)
    
  • 日期
  • 比较:

    let decision = true;
    if(stringElem.split("@@")[2] === 'Date')
            decision = decision && eval(`${new Date(stringElem.split("@@")[0]).getTime()}${stringElem.split("@@")[1]}${new Date(value[i]).getTime()}`)
    
    
    else if(stringElem.split("@@")[2] === 'String')
            decision = decision && eval(`'${stringElem.split("@@")[0]}'${stringElem.split("@@)[1]}'${value[i]}'`)
    
    我尝试使用eval,但无法正确格式化字符串进行比较。谁能帮我解决这个问题?我对Javascript数组方法不是很深入,我想知道是否有更简单的方法来编写相同的代码

    下面是我试图实现的函数的一个非常简单的版本:

        function computeMetricwithConditions() {
    
      const headers = ['name', 'place','stats', 'score', 'date'];
      const data = [['o','b', 22, 2, '4/14/2021']];
      const conditions = [['o', '===','String','name'],
                          ['b', '===','String','place'],
                          ['4/14/2021','>=','Date','date'],
                          [2,'>=','Number','stats']];
      const hashMap = {};
    
      headers.forEach((element,index)=> {
        hashMap[element] = index;
      });
    
      console.log(hashMap);
    
      data.forEach(element => {
    
        let dec = true;
    
        conditions.forEach(elem => {
        let comparisionValue = elem[0];
        let comparisionOperator = elem[1];
        let comparisionType = elem[2];
        let comparisionHeader = elem[3];
    
        if(comparisionType === 'String')
        {dec = dec && eval(`'${comparisionValue}'${comparisionOperator}'${element[hashMap[comparisionHeader]]}'`);
        //console.log(`'${comparisionValue}'${comparisionOperator}'${element[hashMap[comparisionHeader]]}'`);
        }
        else if(comparisionType === 'Date')
        {
          dec = dec && eval(`${new Date(comparisionValue).getTime()}${comparisionOperator}${new Date(element[hashMap[comparisionHeader]]).getTime()}`);
    
        }
    
        else
        {
          dec = dec && eval(`${comparisionValue}${comparisionOperator}${element[hashMap[comparisionHeader]]}`);
        }
    
        console.log(dec);
      });
    
        });
    
        
    
    }
    
    这是我的实现,不确定这是否是一种骇人的方式来完成事情,或者是否有更好的方式来完成同样的事情


    用于日期比较。不知道为什么会发生这种情况。

    我解决这个问题的方法是:

    function computeMetricwithConditions() {
    
      const headers = ['name', 'place', 'stats', 'score', 'date'];
      const data = [['o','b', 22, 2, '4/14/2021']];
      const conditions = [['o', '===','String','name'],['b', '===','String','place'],['4/14/2021','>=','Date','date']];
      const hashMap = {};
    
      headers.forEach((element,index)=> {
        hashMap[element] = index;
      });
    
      data.forEach(element => {
        conditions.forEach(elem => {
          let op;
          switch (elem[1]) {
              case '===':
                  op = (lhs, rhs) => lhs === rhs;
                  break;
              case '>=':
                  op = (lhs, rhs) => lhs >= rhs;
                  break;
          }
            
          let index = headers.indexOf(elem[3]);
    
          switch (elem[2]) {
              case 'String':
                console.log(op(toString(elem[0]), toString(element[index])));
                break;
              case 'Date':
                let date1 = elem[0].split('/');
                let date2 = element[index].split('/');
                console.log(op((new Date(date1[2], date1[0] - 1, date1[1])).getTime(), (new Date(date2[2], date2[0] - 1, date2[1])).getTime()));
                break;
          }
        });
      });
    }
    
    computeMetricwithConditions();
    

    我会为不同的运算符和类型使用开关。

    您可以为运算符使用对象,并使用闭包数组来检查值

    const
    sumif=(summationMetricHeader、标头、值、条件)=>{
    常数
    headers=Object.fromEntries(header.map((k,v)=>[k,v]),
    运算符={
    “>=”:(a,b)=>a>=b,
    “+”:(a,b)=>a+b
    },
    类型={
    日期:(…a)=>a.map(getISODate),
    编号:(a,b)=>[+a,b],
    字符串:(…a)=>a,
    },
    getISODate=string=>string.replace(/(\d+)\/(\d+)\/(\d+)/,(\ux,d,m,y)=>`${y.padStart(4,0)}-${m.padStart(2,0)}-${d.padStart(2,0)}`,
    条件
    .split(“,”)
    .map(s=>s.split('@'))
    .map(([left,op,type,column])=>row=>operators[op](…types[type](left,row[headers[column]]));
    返回值
    .filter(行=>conditions.every(fn=>fn(行)))
    .map(行=>行[Header[summationMetricHeader]]
    .reduce(运算符['+'],0);
    },
    标题=[“月”、“对象”、“日”、“分数”],
    数值=['dec','toy','12/4/2020',50],'dec','pen','14/4/2020',50],'dec','toy','14/4/2020',53],'dec','toy','4/4/2020',50],
    结果=sumif('score',header,value,'12/4/2020@>=@@Date@@day,50@>=@@Number@@score');
    
    控制台日志(结果)您是在询问黑客解决方案还是正确的解决方案?使用
    eval
    没有正确的解决方案。我要求的是正确的解决方案,如果使用
    eval
    没有正确的解决方案,那么最好的方法是什么?
    日期是
    标题中的第四个元素,但是
    数据中的第四个元素是
    2
    。对于所有可能的操作员,我都会使用带有外壳的开关。正如我所说,有一种使用
    eval
    的黑客方法,也有一种不使用
    eval
    的正确方法
    eval
    将是我在所有公司工作过的时候送你回家面试的一个理由。您不应该在生产代码中使用它,最好甚至不知道它。静态代码分析器通常禁止使用它。