代码之家  ›  专栏  ›  技术社区  ›  Leo Messi

通过将每个子数组的第一个元素中的子字符串用作键来组合子数组

  •  5
  • Leo Messi  · 技术社区  · 6 年前

    具有这种形式的二维数组:

    arr = [
            ["12325-a", 1, 1, 1],
            ["43858-b", 3, 4, 1],
            ["84329-a", 6, 5, 2],
            ["18767-b", 0, 9, 0],
            ["65888-b", 5, 4, 4],
    ];
    

    在每个子数组中,第一个元素是一个字符串。

    我想将具有相同端点的子数组组合在一起。在这种情况下,将分为两组: -a -b

    数值应根据IDEX求和。

    所以结果是:

    arr = [
            ["-a", 7, 6, 3],
            ["-b", 8, 17, 5],
    ];
    

    我的解决方案(不起作用):

    let arr = [
      ["12325-a", 1, 1, 1],
      ["43858-b", 3, 4, 1],
      ["84329-a", 6, 5, 2],
      ["18767-b", 0, 9, 0],
      ["65888-b", 5, 4, 4],
    ];
    
    result = arr.reduce(function(acc, curr) {
      if (acc[curr[0].substr(curr[0].length - 2)]) {
        acc[curr[0]] = acc[curr[0]].map(function(val, index) {
    
          if (index) {
            return val + curr[index];
          }
          return val;
        });
      } else {
        acc[curr[0]] = curr;
      }
      return acc;
    }, {});
    
    console.log(result)
    3 回复  |  直到 6 年前
        1
  •  3
  •   Nenad Vracar    6 年前

    你可以先用 reduce 方法创建一个对象,然后 Object.values 获取一个值数组。

    const arr = [
        ["12325-a", 1, 1, 1],
        ["43858-b", 3, 4, 1],
        ["84329-a", 6, 5, 2],
        ["18767-b", 0, 9, 0],
        ["65888-b", 5, 4, 4],
    ];
    
    const result = arr.reduce((r, [str, ...rest]) => {
      let key = str.split(/(\d+)/).pop();
      if(!r[key]) r[key] = [key, ...rest];
      else rest.forEach((e, i) => r[key][i + 1] += e)
      return r;
    }, {})
    
    console.log(Object.values(result))
        2
  •  4
  •   Shubham Khatri    6 年前

    在检查现有值和对现有数据进行映射时,使用的键不正确。你的解决方案看起来像

    let arr = [
      ["12325-a", 1, 1, 1],
      ["43858-b", 3, 4, 1],
      ["84329-a", 6, 5, 2],
      ["18767-b", 0, 9, 0],
      ["65888-b", 5, 4, 4],
    ];
    
    result = arr.reduce(function(acc, curr) {
    
      const key = curr[0].substr(curr[0].length - 2);
      console.log(key)
      if (acc[key]) {
        acc[key] = acc[key].map(function(val, index) {
    
          if (index) {
            return val + curr[index];
          }
          return val;
        });
      } else {
        acc[key] = [curr[0].substr(curr[0].length - 2), ...curr.slice(1)]
      }
      return acc;
    }, {});
    
    console.log(Object.values(result));
        3
  •  0
  •   brk    6 年前

    使用Object to Reduce创建一个对象,其中第一个字符串的最后两个字符将是键。该键的值将是一个数组,该数组将包含下一组值。

    在第二种情况下,如果对象已经有了键,那么获取索引并用它求和值。

    你终于可以了 Object.values 得到一个数组

    let arr = [
      ["12325-a", 1, 1, 1],
      ["43858-b", 3, 4, 1],
      ["84329-a", 6, 5, 2],
      ["18767-b", 0, 9, 0],
      ["65888-b", 5, 4, 4],
    ];
    
    let x = arr.reduce(function(acc, curr) {
      // getting last two characters from first string
      let getSubstring = curr[0].slice(-2);
       //checking if object has a key with this name.
       // if not then create it
      if (!acc.hasOwnProperty(getSubstring)) {
        acc[getSubstring] = [];
        // now iterate over the rest of the values and push them
        for (let i = 1; i < curr.length; i++) {
          acc[getSubstring].push(curr[i])
        }
      } else {
         // if already a key exist then create an array of the elements except the first value
        let newArray = curr.splice(1, curr.length);
        newArray.forEach(function(item, index) {
          acc[getSubstring][index] = acc[getSubstring][index] + item
    
        })
      }
      return acc;
    }, {});
    
    for (let keys in x) {
      x[keys].unshift(keys)
    }
    console.log(Object.values(x))