简体   繁体   English

迭代对象数组并将模板应用于其中的每个对象

[英]Iterate over an array of objects and apply a template to each object within

I don't wish to use JQuery, just to put that upfront.我不想使用 JQuery,只是想把它放在前面。

I have a template for data.我有一个数据模板。 This template will be used for rendering fields of data (or not as the case may be).此模板将用于呈现数据字段(或不视情况而定)。 I've sorted out the matching part of the objects.我已经整理了对象的匹配部分。 The problem I have is when it comes to iterating over the array of objects, and matching said objects to the template.我遇到的问题是在迭代对象数组并将所述对象与模板匹配时。 The results I get all have the same value as the last object in the incoming array.我得到的结果都与传入数组中的最后一个对象具有相同的值。

//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);

when I this, the result puts out a 2-item array with all results matching the data of the "Jill" object.当我这样做时,结果会输出一个 2 项数组,所有结果都与“吉尔”对象的数据匹配。

[{"firstname":"Jill", "lastname":"Smith", "dob":"1986-09-17"},
{"firstname":"Jill", "lastname":"Smith", "dob":"1986-09-17"}]

what I am expecting is:我期待的是:

[{"firstname":"John", "lastname":null, "dob":"1996-04-03"},
{"firstname":"Jill", "lastname":"Smith", "dob":"1986-09-17"}]

My expectation, is that in the forEach call, it should push a new object with matched fields to the empty matched array, however, it doesn't appear to be working that way.我的期望是,在forEach调用中,它应该将具有匹配字段的新对象推送到空的matched数组,但是,它似乎并没有那样工作。 Am I misunderstanding something?我误解了什么吗? I come from a python background, so javascript isn't my first language and I tend to think with a python brain.我来自 python 背景,所以 javascript 不是我的第一语言,我倾向于用 python 大脑思考。

this is the cleanData() function:这是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;
}

So thank you to @VLAZ linking those SO pages.所以感谢@VLAZ 链接这些 SO 页面。 It was a problem in the cleanData function as (s)he so presciently pointed out.正如他(她)有先见之明地指出的那样,这是cleanData函数中的一个问题。 I replaced the let _copy = Object.assign({}, d2) line with let _copy = JSON.parse(JSON.stringify(d2)) which gave me the output I expected.我用let _copy = JSON.parse(JSON.stringify(d2))替换了let _copy = Object.assign({}, d2)行,这给了我预期的输出。 I used this rather than a very fancy deep copy method, because in the template it will only have the dtypes Object , Array , String , or Integer .我使用了这个而不是一个非常花哨的深度复制方法,因为在模板中它只会有 dtypes ObjectArrayStringInteger

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM