怎么根据条件计算数组

const file = "{id:1} * {id:3}";
let data = 0;
const list = [
{ id:1,value:10,key:1},
{ id:2,value:5,key:1},
{ id:3,value:4,key:1},
{ id:1,value:7,key:2},
{ id:2,value:4,key:2},
{ id:3,value:8,key:2},

我想要的是根据file将list中key相同的id=1和id=3的value相乘
结果为

[
{key:1,value: 40},
{key:2,value: 56},
]
阅读 2.3k
4 个回答

你的表达式字符串应该是比较复杂的,类似
const file = "{id:1} - {id:3} + change({id:4} * {id:2}) - {id:5}"
所以id的值可能是任意正整数,所以问题中的计算应该仅仅是针对字符串中的change方法
下面是我的实现:
1、将list的结果转换一下,便于取值计算

const listMap = {};
list.forEach(({id, value, key}) => {
  if (listMap[key]) {
    listMap[key][id] = value;
  } else {
    listMap[key] = {
      [id]: value
    }
  }
});

转换后的结构(listMap)是下面这样的

{
  1: {
    1: 10,
    2: 5,
    3: 4,
    4: 14,
    5: 3
  },
  2: {
    1: 7,
    2: 4,
    3: 8
  }
}

2、遍历listMap,将{id:n}这种转换成对应的value,并将方法(比如change)中的值计算成最后的结果

const file = "{id:1} - {id:3} + change({id:2} * {id:3}) - {id:1}"
const result = [];
Object.keys(listMap).forEach(key => {
  const val = listMap[key];
  // 对应的id是否在list中存在,不存在就不处理
  let valueExist = true;
  // 先把所有{id:n}替换成对应的value
  let str = file.replace(/{id:(\d+)}/g, ($0, $1) => {
    if (!val[$1]) {
      valueExist = false; 
    }
    return val[$1];
  });

  if (valueExist) {
    // 1、如果change方法要单独处理
    // 把所有方法中的参数计算成最后的结果,比如change(14 * 5)转换成change(70)
    str = str.replace(/(?<=\().*?(?=\))/g, $0 => {
      return eval($0)
    });
    // 2、如果当前环境下有change方法,则可以直接执行方法
    // str = eval(str.replace(/\w+\(.*?\)/g, $0 => {
    //   return eval($0)
    // }));
    result.push({
      key,
      value: str
    })
  }
})

最后得到的结果(result)大概是这样的

[
  {
      "key": "1",
      "value": "10 - 4 + change(20) - 10"
  },
  {
      "key": "2",
      "value": "7 - 8 + change(32) - 7"
  }
]

首先遍历list,根据key值划分成对象

{
    1: [...]
    2: [...]
}

然后遍历不同key的数组,将id=1和id=3的数据相乘,
将结果存入新的数组中

list
  .reduce<Array<{ key: number; value: typeof list }>>((prev, cur) => {
    const obj = prev.find((_) => _.key === cur.key);
    if (obj?.value && obj.value.length) {
      obj.value.push(cur);
    } else {
      prev = [...prev, { key: cur.key, value: [cur] }];
    }
    return prev;
  }, [])
  .map((item) => ({
    ...item,
    value:
      (item.value.find((_) => _.id === 1)?.value || 0) *
      (item.value.find((_) => _.id === 3)?.value || 0)
  }));

供参考~

function calculateList(list) {
        var obj = {}, ret = [];
        list.forEach(v => {
            if(obj[v.key]) {
                console.log(obj[v.key][v.id])
                obj[v.key][v.id] = v.value;
            } else {
                obj[v.key] = {};
                obj[v.key][v.id] = v.value;
            }
        });
    for(let key in obj) {
        let value = (obj[key][1] || 0) * (obj[key][3] || 0);
        ret.push({key: +key, value: value});
    }
        return ret;
    }
    calculateList(list)
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题