【问题标题】:Combine sub-arrays by using as a key a sub-string found in the first element of each sub-array通过使用在每个子数组的第一个元素中找到的子字符串作为键来组合子数组
【发布时间】:2019-01-03 08:01:05
【问题描述】:

有一个这种形式的二维数组:

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)

【问题讨论】:

    标签: javascript arrays


    【解决方案1】:

    您可以先使用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】:

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

      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】:

        使用 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))

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-08-10
          • 2011-04-13
          • 2022-07-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多