与JSON混合的Javascript数组无法正常工作

时间:2019-04-05 02:14:05

标签: javascript json

我有这段代码,但是每当我运行 findTimeSlots()时,它都会立即弄乱我的全局数组 apptData ,但是在此函数的任何地方都看不到应该已经改变了。

(ConsoleLog)

(index):69 
(4) [{…}, {…}, {…}, {…}]
0: {service: "A, B", duration: 50, tech: "C"}
1: {service: "B", duration: 30, tech: "C"}
2: {service: "A, D", duration: 60, tech: "A"}
3: {service: "D", duration: 40, tech: "A"}
length: 4
__proto__: Array(0)
(index):45 
(4) [{…}, {…}, {…}, {…}]
0: {service: "A, B", duration: 50, tech: "C"}
1: {service: "B", duration: 30, tech: "C"}
2: {service: "A, D", duration: 60, tech: "A"}
3: {service: "D", duration: 40, tech: "A"}
length: 4
__proto__: Array(0)

///////////////////////////////////////////////// ///////////////////////////////////////////////////// ///////////////////////////////////////////////////// ////

var apptData = [];
function addApptData(serviceName, rawDuration, selectedTech){
    apptData.push({
        'service': serviceName,
        'duration': rawDuration,
        'tech' : selectedTech
    })
}
function reduceApptData(index){
    apptData.splice(index, 1);
}
function findTimeSlots(dateStr){
    console.log(apptData);             //* Index 45 *//
    var final = new Array();
    var service, duration;
    for(var i = 0; i < apptData.length; i++){
        var duplicated = false;
        for(var j = 0; j < final.length; j++){
            if(final[j].tech == apptData[i].tech){
                service = ", "+apptData[i].service;
                final[j].service += service;
                duration = apptData[i].duration;
                final[j].duration += duration;
                duplicated = true;
                break;
            }
        }
        if(!duplicated){
            final.push(apptData[i]);
        }
    }
 }
addApptData("A", 20, "C");
addApptData("B", 30, "C");
addApptData("A", 20, "A");
addApptData("D", 40, "A");
console.log(apptData);                //* Index 69 *//
// If I remove the line below, I get the expected result, when I try to 
// run with this line it will mess up apptData[]
findTimeSlots("");

我期望的是

0: {service: "A", duration: 20, tech: "C"}
1: {service: "B", duration: 30, tech: "C"}
2: {service: "A", duration: 20, tech: "A"}
3: {service: "D", duration: 40, tech: "A"}
length: 4
__proto__: Array(0)

所以基本上我希望它保持不变。

我想将 var apptData 合并到 findTimeSlots()

中的 var final

调试后,我发现我的 apptData 出于某些原因意外更改。

我怀疑这很琐碎,但我无法终生明白。

3 个答案:

答案 0 :(得分:1)

您应该制作apptData的浅表副本。

您应该注意JavaScript的一件事是按值分配与按引用分配之间的区别。

当将数字(即2、23),字符串(即'aaa','123')等原始数据类型分配给变量时,该变量将包含原始值。

另一方面,当将非原始数据类型(数组,对象,函数)分配给变量时,该变量包含引用(“指向”对象在内存中的位置)而不是值本身。

要回答您的问题,您应该制作apptData的浅表副本,而不是直接引用它。

假设您的apptData是(非嵌套)对象的数组,这是使用ES6的扩展语法对其进行浅表复制的简单方法:

const apptDataCopy = apptData.map(serviceObject => ({...serviceObject}));

从那里,您可以对apptDataCopy进行任何更改,而不会影响原始的apptData

答案 1 :(得分:1)

在这个小例子中解释了发生的事情:

let a = {test: 10};
let b = a;
b.text = 11;
console.log(a); //this will print {test: 11}

由于a是对象,因此分配let b = a;时实际上是在保存对a的引用,而不是克隆a

您需要克隆对象apptData[i],然后See this answer

因此,您应该推送克隆的final.push(apptData[i]);而不是apptData[i]

希望有帮助。

答案 2 :(得分:1)

var apptData = [], typeSelectedTech = new Set(), finalData =[], tmpObj = {serviceName: '', rawDuration: 0}
const addApptData = (serviceName, rawDuration, selectedTech)=> {
    apptData.push({
        serviceName,
        rawDuration,
        selectedTech
    })
    if (typeSelectedTech.has(selectedTech)) {
      finalData.push({serviceName: tmpObj.selectedTech + ',' + serviceName, rawDuration: tmpObj.rawDuration + rawDuration, selectedTech})
    }else {
      tmpObj = {
          serviceName,
          rawDuration,
          selectedTech
      }
      typeSelectedTech.add(selectedTech)

    }
}

addApptData("A", 20, "C");
addApptData("B", 30, "C");
addApptData("A", 20, "A");
addApptData("D", 40, "A");
console.log(finalData);
console.log(apptData);

首先,我相信您已经解决了问题,我的回答仅供沟通。

我尝试了重写方法,可以获取原始数据和目标数据。尽管它会产生多个全局变量,但我无法想到其他方法。

因此,作为交流,我希望其他人可以有更好的方法。