2017-02-16 61 views
2

我有类似以下数据:学生优化阵列反相

名单和学校,他们参加

[ 
    { 
     "uid": 100, 
     "name": "Adam", 
     "school": { 
      "id": 1, 
      "name": "NYHS" 
     } 
    }, 
    { 
     "uid": 101, 
     "name": "Bob", 
     "school": { 
      "id": 2, 
      "name": "PAHS" 
     } 
    }, 
    { 
     "uid": 102, 
     "name": "Charles", 
     "school": { 
      "id": 1, 
      "name": "NYHS" 
     } 
    }, 
    { 
     "uid": 103, 
     "name": "David", 
     "school": { 
      "id": 3, 
      "name": "MMDS" 
     } 
    } 
] 

我想将它与参加学生转变为学校名单它。

[ 
    { 
     "id": 1, 
     "name": "NYHS", 
     "students": [ 
      { 
       "uid": 100, 
       "name": "Adam" 
      }, 
      { 
       "uid": 102, 
       "name": "Charles" 
      }, 
     ] 
    }, 
     "id": 2, 
     "name": "NYHS", 
     "students": [ 
      { 
       "uid": 101, 
       "name": "Bob" 
      } 
     ] 
    }, 
     "id": 3, 
     "name": "MMDS", 
     "students": [ 
      { 
       "uid": 103, 
       "name": "David" 
      } 
     ] 
    }, 
] 

我有一个工作版本,但它很长,可能不是高性能。有没有更快/更快的方法来做到这一点?

真的不管用什么语言。

试过使用的地图/减少,我得到了独特的学校,但不知道如何将学生合并到它。

$schools = array_reduce(
    array_map(function ($a) { 
     return $a['school']; 
    }, $students), 
    function ($s, $i) { 
     if (count(array_filter($s, function ($j) use ($i) { 
      return $j['id'] == $i['id']; 
     })) == 0) { 
      array_push($s, $i); 
     } 
     return $s; 
    }, 
    array() 
); 
+0

我希望你有使用reduce方法来分组数据 –

+0

JavaScript或PHP? – nnnnnn

+0

@nnnnnn没关系。要么工作 – YarGnawh

回答

2

我很可能最小化,通过使用到.reduce()一个呼叫以产生具有为每个学校一个属性,该属性对象到最终输出数组的对象,然后映射循环:

var input = [ // whitespace compressed to avoid vertical scrolling 
 
    { "uid": 100, "name": "Adam", "school": { "id": 1, "name": "NYHS" } }, 
 
    { "uid": 101, "name": "Bob", "school": { "id": 2, "name": "PAHS" } }, 
 
    { "uid": 102, "name": "Charles", "school": { "id": 1, "name": "NYHS" } }, 
 
    { "uid": 103, "name": "David", "school": { "id": 3, "name": "MMDS" } } 
 
] 
 

 
var schoolObj = input.reduce(function(p,c) { 
 
    if (!(c.school.id in p)) 
 
    p[c.school.id] = { id: c.school.id, name: c.school.name, students: [] } 
 
    p[c.school.id].students.push({ uid: c.uid, name: c.name }) 
 
    return p 
 
}, {}) 
 

 
var schoolArr = Object.keys(schoolObj).map(function(s) { return schoolObj[s] }) 
 

 
console.log(schoolArr)

1

下面是做这件事:

function myTransform(input) { 

    // Store the output of the transform as an object 
    // Here I assume that the school id is unique 
    var output = {}; 

    input.forEach((e) => { 

    if (!output[e.school.id]) { 

     // If the school id doesn't exist in the output then generate it, and put the school & student data into it 
     output[e.school.id] = { 
     id: e.school.id, 
     name: e.school.name, 
     students: [{ 
      uid: e.uid, 
      name: e.name 
     }] 
     }; 
    } else { 

     // If the school id exists in the output, then push the student data into it 
     output[e.school.id].students.push({ 
     uid: e.uid, 
     name: e.name 
     }); 
    } 
    }); 

    // Convert the output into an array 
    return Object.keys(output).map((e) => output[e]); 
} 

我用了一个对象的输出存储,以避免使用嵌套循环(我不知道这是做到这一点的最好办法虽然)。最后,我将该对象转换为一个数组。

1

var arr = [{"uid":100,"name":"Adam","school":{"id":1,"name":"NYHS"}},{"uid":101,"name":"Bob","school":{"id":2,"name":"PAHS"}},{"uid":102,"name":"Charles","school":{"id":1,"name":"NYHS"}},{"uid":103,"name":"David","school":{"id":3,"name":"MMDS"}}]; 
 

 
var result = Object.values(            // get the values of the hash object 
 
    arr.reduce(function(hash, o) { 
 
     var id = o.school.id;            // get the school id 
 
     hash[id] = hash[id] || {id: id, name: o.school.name, students: []}; // check if the school is already in the hash object, if not create add it 
 
     hash[id].students.push({id: o.id, name: o.name});     // add this student to its students array 
 
     return hash; 
 
    }, {}) 
 
); 
 

 
console.log(result);

+0

Object.values()'一旦稳定并支持所有当前浏览器,肯定会派上用场。 (我猜总有一个polyfill。) – nnnnnn

1

下面是一个PHP版本RETA插入你可能拥有的所有其他领域。

$output = array_reduce($input, function($result, $item) { 
    $id = $item["school"]["id"]; 
    if (!isset($result[$id])) { 
     $result[$id] = array_merge($item["school"], ["students" => []]); 
    } 
    $result[$id]["students"][] = array_diff_key($item, ["school" => null]); 
    return $result; 
}, []); 

Try it online