Homelab, Linux, JS & ABAP (~˘▾˘)~

## [JavaScript] Itereate through array of nested objects and delete specific objects

```[
{
"NodeId": 1,
"HierarchyLevel": 1,
"type": "folder",
"nodes": [
{
"NodeId": 2,
"HierarchyLevel": 2,
"type": "folder",
"nodes": [
{
"NodeId": 3,
"HierarchyLevel": 3,
"type": "category"
}
]
},
{
"NodeId": 4,
"HierarchyLevel": 2,
"type": "category",
"nodes": [
{
"NodeId": 5,
"HierarchyLevel": 3,
"type": "file"
}
]
}
]
},
{
"NodeId": 6,
"HierarchyLevel": 1,
"type": "folder",
"nodes": [
{
"NodeId": 7,
"HierarchyLevel": 2,
"type": "category"
}
]
}
]
```

My task was to get rid of every Node which has no subnodes of type file at the last level of the hierachy. So for this example the result I needed was an array containing only the nodes 1,2,4,5.
Of course in reality the nested structure was way more complex. My approach was a recursive function which checks every element’s type and nodes length property and calls itself if there are any subnodes. Also it is recommended to loop backwards through the array while deleting from it.

```
const removeEmptyNodes = nodes => {
for (let i = nodes.length - 1; i > -1; i--) {
const n = nodes[i]
//call function recursive to go deeper through the nested structure
if (n.nodes) removeEmptyNodes(n.nodes)
//remove element if it's not a file and has no subnodes
if (n.type !== 'file' && (!n.nodes || n.nodes.length === 0)) nodes.splice(i, 1)
}
}

// nodes contains the array data from above
removeEmptyNodes(nodes)
```

## [nodejs] iterate through fetch response headers

```        const response = await fetch("https://example.com/api")

for (const [key, value] of response.headers) {
console.log(key, value)
}
```

An alternative would be `forEach()`

```        response.headers.forEach((value, key) => {
console.log(value, key)
})
```

Or using the `entries()` iterator (ES8)

```          const headerIterator = response.headers.entries()
```

To add a new header just use `set()`

```response.set(key, value)
```

## [JavaScript] Iterate

While Loops

```var myArr = [];
var i = 0;

while(i < 5) {
myArr.push(i);
i++;
}
```

For Loops

```var myArr = [];

// for ([initialization]; [condition]; [final-expression])
for (var i = 0; i < 5; i++) {
myArr.push(i);
}
```

Iterate through an Array with a `For Loop`

```var myArr = [ 2, 3, 4, 5, 6];
var total = 0;

for (var i = 0; i < myArr.length; i++) {
total += myArr[i];
}
```

Nesting `For Loops`

```var myArr = [
[1,2], [3,4], [5,6]
];

for (var i=0; i < myArr.length; i++) {
for (var j=0; j < myArr[i].length; j++) {
console.log(myArr[i][j]);
}
}
```

For…In Loops

Iterate through all the keys within an object.

```let users = {
Max: {
age: 27
},
Mira: {
age: 32
},
Rich: {
age: 48
}
};

for (let user in users) {
console.log(user); // logs: Max, Mira, Rich
if (users[user].age > 40) {
console.log(`\${user} is old.`);
}
}
```

Do…While Loops

A `do...while` loop ensures that the code inside the loop will run at least once.

```var myArr = [];
var i = 0;
do {
myArr.push(i);
i++;
} while (i < 5);
```

Replace Loops using Recursion

```/* For Loop */
function multiply(arr, n) {
var product = 1;
for (var i = 0; i < n; i++) {
product *= arr[i];
}
return product;
}

/* Replace For Loop with Recursion */
function multiply(arr, n) {
if (n <= 0) {
return 1;
} else {
return multiply(arr, n - 1) * arr[n - 1];
}
}
```

Note: Recursive functions must have a base case when they return without calling the function again (in this example, when `n <= 0`), otherwise they can never finish executing.

```/* Count to n */
function countup(n) {
if (n < 1) {
return [];
} else {
const countArray = countup(n - 1);
countArray.push(n);
return countArray;
}
}

console.log(countup(5)); // [ 1, 2, 3, 4, 5 ]
```

Note: The push happens last, after the recursive call has returned. Thats why the value of `n` decreases, but the values in the final array are increasing.

```/* Create a Range of Numbers */
function rangeOfNumbers(startNum, endNum) {
if (startNum == endNum) {
return [startNum];
} else if (startNum < endNum) {
const rangeArray = rangeOfNumbers(startNum + 1, endNum);
rangeArray.unshift(startNum);
return rangeArray;
}
};

console.log(rangeOfNumbers(5, 10)); // [ 5, 6, 7, 8, 9, 10 ]
```