Skip to content
Advertisement

Why only last element is showing of an array instead of all elements in JavaScript

I am trying to retrieve certain information from a json data and want to make a new key-value pair array. But its only returning the last element instead of all elements.

My code is following:

const input = 
{
  "file1": {
    "function1": {
      "calls": {
        "105": {
          "file": "file1",
          "function": "function2"
        },
        "106": {
          "file": "file1",
          "function": "function3"
        }
      },
      "points": {
        "106": "106"
      }
    },
    "function2": {
      "calls": {
        "109": {
          "file": "file1",
          "function": "function2"
        }
      },
      "points": {
        "109": "111"
      }
    },
    "function3": {
      "calls": {},
      "points": {
        "132": "135"
      }
    }
  }
}

function transformData(input) {
  let  res = [];
  Object.entries(input).map(([fileName, fileObject]) => {
    Object.entries(fileObject).map(([functionName, functionObject]) => {
      Object.entries(functionObject).map(([functionKey, functionValue]) => {
        if(functionKey === "calls") {
          Object.entries(functionValue).map(([callKey, callObject]) => {
            res = {"source": functionName, "target": callObject['function']}
            //console.log(res); // here all elements get printed out
          });
        }   
      });
    });
   });
  return res;
 }

 const result = transformData(input);
 console.log(result) // only giving {source:"function2", target:"function2"}

Here as the result I want new source, target pairs where the source is the key under file (function1, function2). Target is the value of the nested key “function” inside the key “calls” (function2, function3, function2). Here the number of files and functions will be more. But some functions may not have “calls” data at all. So, the result will look like following:

[
  {
    source: "function1",
    target: "function2"
  },
  {
    source: "function1",
    target: "function3"
  },
  {
    source: "function2",
    target: "function2"
  }
]

Can anyone please help me out to get the correct output. Thank you for your time.

Advertisement

Answer

I’m not sure how “guaranteed” your object structure is, but assuming you want to iterate through all file* key and get the function mappings, this should do the trick.

const input = 
{
  "file1": {
    "function1": {
      "calls": {
        "105": {
          "file": "file1",
          "function": "function2"
        },
        "106": {
          "file": "file1",
          "function": "function3"
        }
      },
      "points": {
        "106": "106"
      }
    },
    "function2": {
      "calls": {
        "109": {
          "file": "file1",
          "function": "function2"
        }
      },
      "points": {
        "109": "111"
      }
    },
    "function3": {
      "calls": {},
      "points": {
        "132": "135"
      }
    }
  }
}

const result = [];

for(const key in input) {
  if (key.includes('file')) {
    const functions = Object.keys(input[key]);
    for (const func of functions) {
      const funcObject = input[key][func];
      for (const call in funcObject.calls) {
        const callObj = funcObject.calls[call];
        result.push({source: func, target: callObj.function});
      }
    }
  }
}
console.log(result);
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement