在 Javascript 中合并数组中的链接数据
Merging linked Data in Array in Javascript
我有一个简单的任务是在 JSON 中重新排列几个数组,因此 ractive.js 可以更好地处理它。但是有点得意忘形,结果不是特别理想。
我的初始数组示例:
[{
"_id": 1,
"type": "person",
"Name": "Hans",
"WorksFor": ["3", "4"],
}, {
"_id": 2,
"type": "person",
"Name": "Michael",
"WorksFor": ["3"],
}, {
"_id": 3,
"type": "department",
"Name": "Marketing"
}, {
"_id": 4,
"type": "department",
"Name": "Sales"
}, {
"_id": 5,
"type": "person",
"Name": "Chris",
"WorksFor": [],
}]
因此,对于给定的部门,我想要一个 ractive 方法来为我提供在该部门工作的所有人员(以及他们工作的部门列表)。类似于:
[{
"_id": 1,
"type": "person",
"Name": "Hans",
"WorksFor": ["3", "4"],
"Readable": ["Marketing", "Sales"]
}, {
"_id": 2,
"type": "person",
"Name": "Michael",
"WorksFor": ["3"],
"Readable": ["Sales"]
}]
以某种方式出现的函数与此类似:
function imsorryforthis() {
let output = [];
let tempdocs = this.get('docs'); //as this happens in a ractive method,
//"this.get" is neccesary for binding
for (var i = 0; i < tempdocs.length; i++) {
if (_.contains(tempdocs[i].WorksFor, givenDepartment)) { //I used underscore.js here
let collectedDepartmentData = [];
if (tempdocs[i].WorksFor.length > 0) {
for (var f = 0; f < tempdocs[i].WorksFor.length; f++) {
for (var g = 0; g < tempdocs.length; g++) {
if (tempdocs[i].WorksFor[f] == tempdocs[g]._id) {
let actualDepartmentData = {};
actualDepartmentData = tempdocs[g];
collectedDepartmentData.push(actualDepartmentData);
}
}
}
}
tempdocs[i].Readable = collectedDepartmentData;
output.push(tempdocs[i]);
}
}
return output;
}
我也把它放在 Fiddle 中以使其更易读。
由于这个怪物不知何故确实有效(我自己也很惊讶),感觉就像用右手在头上挠左耳(同时被一群绝望的数学家不断大喊大叫)。
也许有人知道更漂亮、更聪明的方法(或编译 JavaScript 的方法,所以这再也见不到曙光了)。
首先,你的数据结构没有设计好。您不应该在同一个数组中返回人员和部门。如果可能,尝试重新设计初始数据结构,通过将人员和部门分离到不同的结构中,使其更加模块化。但是,如果您坚持使用相同的数据结构,则可以将代码编写得更好一些。请在下面找到代码。希望能帮助到你!
function mapPeopleDepartment() {
var deptMap = {},peopleList = [];
//Iterate through the initialArray and separate out the department into a hashmap deptMap and people into a new peopleList
for(var i=0; i < initArray.length; i++) {
var obj = initArray[i];
obj.type == "department" ? deptMap[obj._id] = obj.Name : peopleList.push(obj);
}
//Iterate through the peopleList to map the WorksFor array to a Readable array
for(var i=0; i < peopleList.length; i++) {
var person = peopleList[i];
person.Readable = _.map(person.WorksFor, function(dept){return deptMap[dept]});
}
return peopleList;
}
先构建地图department_id => department_name
:
let departments = {};
for (let x of data) {
if (x.type === 'department') {
departments[x._id] = x.Name;
}
}
然后,迭代 Persons 并从该映射填充 Readable
数组:
for (let x of data) {
if (x.type === 'person') {
x.Readable = x.WorksFor.map(w => departments[w]);
}
}
最后,提取特定部门的人员:
personsInSales = data.filter(x =>
x.type === 'person' && x.WorksFor.includes('3'));
我有一个简单的任务是在 JSON 中重新排列几个数组,因此 ractive.js 可以更好地处理它。但是有点得意忘形,结果不是特别理想。
我的初始数组示例:
[{
"_id": 1,
"type": "person",
"Name": "Hans",
"WorksFor": ["3", "4"],
}, {
"_id": 2,
"type": "person",
"Name": "Michael",
"WorksFor": ["3"],
}, {
"_id": 3,
"type": "department",
"Name": "Marketing"
}, {
"_id": 4,
"type": "department",
"Name": "Sales"
}, {
"_id": 5,
"type": "person",
"Name": "Chris",
"WorksFor": [],
}]
因此,对于给定的部门,我想要一个 ractive 方法来为我提供在该部门工作的所有人员(以及他们工作的部门列表)。类似于:
[{
"_id": 1,
"type": "person",
"Name": "Hans",
"WorksFor": ["3", "4"],
"Readable": ["Marketing", "Sales"]
}, {
"_id": 2,
"type": "person",
"Name": "Michael",
"WorksFor": ["3"],
"Readable": ["Sales"]
}]
以某种方式出现的函数与此类似:
function imsorryforthis() {
let output = [];
let tempdocs = this.get('docs'); //as this happens in a ractive method,
//"this.get" is neccesary for binding
for (var i = 0; i < tempdocs.length; i++) {
if (_.contains(tempdocs[i].WorksFor, givenDepartment)) { //I used underscore.js here
let collectedDepartmentData = [];
if (tempdocs[i].WorksFor.length > 0) {
for (var f = 0; f < tempdocs[i].WorksFor.length; f++) {
for (var g = 0; g < tempdocs.length; g++) {
if (tempdocs[i].WorksFor[f] == tempdocs[g]._id) {
let actualDepartmentData = {};
actualDepartmentData = tempdocs[g];
collectedDepartmentData.push(actualDepartmentData);
}
}
}
}
tempdocs[i].Readable = collectedDepartmentData;
output.push(tempdocs[i]);
}
}
return output;
}
我也把它放在 Fiddle 中以使其更易读。
由于这个怪物不知何故确实有效(我自己也很惊讶),感觉就像用右手在头上挠左耳(同时被一群绝望的数学家不断大喊大叫)。
也许有人知道更漂亮、更聪明的方法(或编译 JavaScript 的方法,所以这再也见不到曙光了)。
首先,你的数据结构没有设计好。您不应该在同一个数组中返回人员和部门。如果可能,尝试重新设计初始数据结构,通过将人员和部门分离到不同的结构中,使其更加模块化。但是,如果您坚持使用相同的数据结构,则可以将代码编写得更好一些。请在下面找到代码。希望能帮助到你!
function mapPeopleDepartment() {
var deptMap = {},peopleList = [];
//Iterate through the initialArray and separate out the department into a hashmap deptMap and people into a new peopleList
for(var i=0; i < initArray.length; i++) {
var obj = initArray[i];
obj.type == "department" ? deptMap[obj._id] = obj.Name : peopleList.push(obj);
}
//Iterate through the peopleList to map the WorksFor array to a Readable array
for(var i=0; i < peopleList.length; i++) {
var person = peopleList[i];
person.Readable = _.map(person.WorksFor, function(dept){return deptMap[dept]});
}
return peopleList;
}
先构建地图department_id => department_name
:
let departments = {};
for (let x of data) {
if (x.type === 'department') {
departments[x._id] = x.Name;
}
}
然后,迭代 Persons 并从该映射填充 Readable
数组:
for (let x of data) {
if (x.type === 'person') {
x.Readable = x.WorksFor.map(w => departments[w]);
}
}
最后,提取特定部门的人员:
personsInSales = data.filter(x =>
x.type === 'person' && x.WorksFor.includes('3'));