Agrupar agrupación de objetos Javascript por ID

Lo que quiero lograr es agrupar objetos dentro de una matriz si los dos primeros dígitos de las ID coinciden. Entonces, dada la siguiente matriz de objetos, quiero convertir esta ORIGINAL ARRAY:

[
    {
        "id": "0100",
        "name": "name 1",
        "message": "Lorem blah blah 1"
    },
    {
        "id": "0101",
        "name": "",
        "message": "Lorem blah blah 1.1"
    },
    {
        "id": "0200",
        "name": "name 2",
        "message": "Lorem blah blah 2"
    },
    {
        "id": "0201",
        "name": "",
        "message": "Lorem blah blah 2.1"
    },
    {
        "id": "0202",
        "name": "",
        "message": "Lorem blah blah 2.2"
    },
    {
        "id": "0300",
        "name": "name 3",
        "message": "Lorem blah blah 3"
    },
    {
        "id": "0301",
        "name": "",
        "message": "Lorem blah blah 3.1"
    },
    {
        "id": "0302",
        "name": "",
        "message": "Lorem blah blah 3.2"
    },
    {
        "id": "0303",
        "name": "",
        "message": "Lorem blah blah 3.3"
    },
    {
        "id": "0304",
        "name": "",
        "message": "Lorem blah blah 3.4"
    }
]

en este NUEVO ARRAY:

[
    {
        "id": "0100",
        "name": "name 1",
        "message": [
            "Lorem blah blah 1",
            "Lorem blah blah 1.1"
        ]
    },
    {
        "id": "0200",
        "name": "name 2",
        "message": [
            "Lorem blah blah 2",
            "Lorem blah blah 2.1",
            "Lorem blah blah 2.2"
        ]
    },
    {
        "id": "0300",
        "name": "name 3",
        "message": [
            "Lorem blah blah 3",
            "Lorem blah blah 3.1",
            "Lorem blah blah 3.2",
            "Lorem blah blah 3.3",
            "Lorem blah blah 3.4"
        ]
    }
]

La cuestión clave a tener en cuenta es que si los dos primeros dígitos de las ID son idénticos, entonces agregue los mensajes en esos objetos juntos como se ve en el NUEVO ARRAY.

Como todos pueden ver, @Nenad Vracar ha demostrado una respuesta decente al desafío anterior, sin embargo, tengo una pregunta adicional que involucra otra matriz más:

`var data2 = [{"CandidateName": "Mary", "relatedId": ["0100"]},{ "CandidateName": "John", "relatedId": ["0200"]},{ "CandidateName":"Peter", "relatedId": ["0300"]},{ "CandidateName": "Paul", "relatedId": ["0300"]}];`

en el que quiero extraer el 'candidatoName' y agregarlo como una matriz a la matriz original, "resultado".

He intentado un bucle data2.forEach dentro del bucle data1.reduce pero parece que se bloquea.

var result = data.reduce(function(r, el) {

  // THIS INNER LOOP MAKES THE BROWSER HANG!!!
  data2.forEach(function (a){
    console.log('a',a); 
  });

  var e = el.id.slice(0, 2);
  if (!o[e]) {
    o[e] = {
      id: el.id,
      name: el.name,
      message: []
    }
    r.push(o[e]);
  }
  o[e].message.push(el.message);
  return r;
}, [])

Me pregunto si hay un método más elegante y sofisticado que no se rompa.

Respuestas a la pregunta(2)

Su respuesta a la pregunta