JS算法题目2

输入:['A1','B1','C1','E1','A2','C2','D2','H2','A3','E3']  
//要求输出二维数组 对数组进行分组,
输出:[
    ['A1','B1','C1','E1'],
    ['A2','C2','D2','H2'],
    ['A3','E3']
]  
阅读 2.5k
4 个回答

如果使用 lodash,那就是一句话的事儿,

import _ from "lodash";

const inputData = ["A1", "B1", "C1", "E1", "A2", "C2", "D2", "H2", "A3", "E3"];

const result = _(inputData)
    .groupBy(s => s.substr(1))
    .values()
    .value();

console.log(result);

但是要算法,其实就是自己写那个 groupBygroupBy 的结果肯定是键值对(用 List 还是用 Map 另说)。其中键是组名,在这里就是第 1 个字母之后的内容;值是一个列表,保存着分到这个组中的元素集,看注释

function group(data, keySelector) {
    const groups = data
        // 把一个元素变成单个键值对,这一步可以合并到下面的 reduce 中
        .map(s => [keySelector(s), s])
        .reduce((map, [key, s]) => {
            //        ^^^^^^^^ 这是一个参数解构语法
            // 下面这句是从 map 中找到 key 对应的值集,
            // 如果没有先初始化为空集,
            // 然后把元素放了这个值集中去
            (map[key] ??= []).push(s);
            return map;
        }, {}); // reduce 的结果是一个 JS 对象,也可以说是一个 map

    // 把这个 map 处理成列表,因为结果中不需要 key,直接取值集的列表就行
    return Object.values(groups);
}

// 别忘了 group 的第 2 个参数,用来取分组用的 Key
console.log(group(inputData, s => s.substr(1)));

上面这个例子是用 Map 来保存的键值对,反正都写了,再补个 List 保存键值对的,注释就不写了,应该能理解

function group2(data, keySelector) {
    return data
        .map(s => [keySelector(s), s])
        .reduce((list, [key, s]) => {
            const pair = list.find(pair => pair[0] === key);
            if (pair) {
                pair[1].push(s);
            } else {
                list.push([key, [s]]);
            }
            return list;
        }, [])
        .map(pair => pair[1]);
}

console.log(group2(inputData, s => s.substr(1)));
const temp = ["A1", "B1", "C1", "E1", "A2", "C2", "D2", "H2", "A3", "E3"];

const grouping = (arr) => {
  const getGroupId = (str) => {
    return str[str.length - 1];
  };

  const ans = [];

  for (let i = 0; i < arr.length; ++i) {
    const groupId = getGroupId(arr[i]);

    if (!ans[groupId]) ans[groupId] = [];

    ans[groupId].push(arr[i]);
  }

  return ans.filter(Boolean);
};

console.log(grouping(temp));
Object.values(["A1", "B1", "C1", "E1", "A2", "C2", "D2", "H2", "A3", "E3"].reduce((res,str) => {
    var index = str.match(/\d/)[0];
    res[index] ||= [];
    res[index].push(str);
    return res;
},{}));

这里考虑到数字可能不连续所以用的key-value来作为集合,如果是连续的可以直接使用数组,可以少一次遍历

const arr = ['A1', 'B1', 'C1', 'E1', 'A2', 'C2', 'D2', 'H2', 'A3', 'E3']

const res = []
let temp = {}
arr.map(v => {
  let value = v.match(/\d$/)
  if (temp[value[0]]) {
    temp[value[0]].push(value['input'])
  } else {
    temp[value[0]] = [value['input']]
  }
})
console.log(Object.values(temp));
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏