【发布时间】:2021-12-26 18:45:44
【问题描述】:
我不想使用 JQuery,只是把它放在前面。
我有一个数据模板。该模板将用于渲染数据字段(或不用于渲染)。我已经整理出了对象的匹配部分。我遇到的问题是在迭代对象数组并将所述对象与模板匹配时。我得到的结果都与传入数组中的最后一个对象具有相同的值。
//template
//actual template/incoming data is much more than this, but im keeping it a simple example
const template = {"firstname":null, "lastname":null, "dob":null}
//incoming (from a fileupload, but i will put it here an example)
const incoming = [{"firstname":"John", "dob":"1996-04-03"},
{"firstname":"Jill", "lastname":"Smith", "dob":"1986-09-17"}]
function readFile() { // function read the files from upload
const fileIn = document.querySelector('#file-input'); //finds the input area in the form
var reader = new FileReader();
reader.onload = onReaderLoad;
reader.readAsText(filein.files[0]); //gets the uploaded json file
};
function onReaderLoad(event) {
const obj = JSON.parse(event.target.result); //parse the uploaded file
const matched = []; //empty array to push matched objects to
obj.forEach(el => {
//i left this function out of this example because it works as expected, returns 1 object
matched.push(cleanData(el)); //call the function that matches the template and incoming
});
console.log(matched)
};
document.getElementById('file-input).addEventListener('change', onChange);
当我这样做时,结果会输出一个 2 项数组,其中所有结果都与“Jill”对象的数据匹配。
[{"firstname":"Jill", "lastname":"Smith", "dob":"1986-09-17"},
{"firstname":"Jill", "lastname":"Smith", "dob":"1986-09-17"}]
我期待的是:
[{"firstname":"John", "lastname":null, "dob":"1996-04-03"},
{"firstname":"Jill", "lastname":"Smith", "dob":"1986-09-17"}]
我的期望是,在forEach 调用中,它应该将具有匹配字段的新对象推送到空的matched 数组中,但是,它似乎并没有以这种方式工作。我是不是误会了什么?我来自 python 背景,所以 javascript 不是我的第一语言,我倾向于用 python 大脑思考。
这是cleanData() 函数:
function cleanData(d1, d2=template) {
let _copy = Object.assign({}, d2) //makes a copy
const commonKeys = getKeys(d1, _copy) //returns a list of keys found in both
commonKeys.forEach(element => {
//is it an object, but not array?
if((d1[element] instanceof Object) && (Array.isArray(d1[element]))){
const subKeys = getKeys(d1[element], _copy[element]);
subKeys.forEach(el => {
_copy[element][el] = d1[element][el];});
}else if(Array.isArray(d1[element])){ //is it an array?
var objList = [];
for(var i=0; i<d1[element].length; ++i){
if((d1[element] instanceof Object) && (Array.isArray(d1[element]))){
const temp=d1[element][i];
//array in _copy will always be length 0
const temp_fix = cleanData(temp, _copy[element][0])
objList.push(temp_fix);
_copy[element] = objList;
}else { _copy[element] = d1[element]}
}
} else { //if not array or obj
_copy[element] = d1[element]
}
});
return _copy;
}
【问题讨论】:
-
很大程度上取决于
cleanData函数的作用...顺便说一句,您最好还是使用matched = obj.map(el => cleanData(el)) -
cleanData 获取传入的 JSON 对象并将键与模板匹配,并返回具有部分或全部匹配字段的新对象。
-
你已经说了它的作用。 如何 这才是最重要的。 JavaScript 处理引用的方式很重要。
-
您的
cleanData很可能会执行类似于Object.assign(template, otherObject)的操作,它会改变模板。见A javascript design pattern for options with default values? | JavaScript equivalent of jQuery's extend method | How do I correctly clone a JavaScript object? | Is this a good way to clone an object in ES6? -
"嘿,你怎么知道的" - 因为@VLAZ 是个英雄! :-)
标签: javascript