I'm trying using excel4node to convert my data into excel,
here is my code:
names = ['AA','BB','CC']
names.forEach((title, index) => {
sheet.cell(1, index, 1, index + 1, true).string(title);
index += 2;
});
the problem is i want to only use odd number as index in this loop.
expecting sheet.cell code in loop like this:
sheet.cell(1, "1", 1, "2", true).string(title[0])
sheet.cell(1, "3", 1, "4", true).string(title[1])
sheet.cell(1, "5", 1, "6", true).string(title[2])
so how do i skip the even index number in for each loop
I tried used index += 2 or in the beginning of the loop (title, index = 1) or use continue, but won't work...
please help, thanks
I think you can do like this.
sheet.cell(1, 2 * index + 1, 1, 2 * index + 2, true).string(title);
index += 2 does nothing. index is a local variable in a callback, its scope ends at the end of the callback body.
Also continue does nothing since it's not a for loop.
You can try:
names.forEach((title, index) => {
if (index % 2 === 0) return;
sheet.cell(1, index, 1, index + 1, true).string(title);
});
Related
With given array on unique numbers which are always greater than 0 I need to find all possible unique combinations of those numbers that are equal to a certain number when summed.
For example, getNumberComponents([7, 4, 3, 2, 5, 6, 8, 1], 8) should return
[ [ 7, 1 ], [ 4, 3, 1 ], [ 3, 5 ], [ 2, 5, 1 ], [ 2, 6 ], [ 8 ] ] because sum of all numbers in every subarray equals 8.
My solution:
function getNumberComponents(numArray, number) {
const arrayLength = numArray.length;
const allVariants = [];
function findComponents(currentIndex = 0, currentVariant = []) {
while (currentIndex < arrayLength) {
const currentElement = numArray[currentIndex];
const currentSum = currentVariant.reduce((acc, cur) => acc + cur, 0);
const sumWithCurrent = currentSum + currentElement;
if (sumWithCurrent === number) {
allVariants.push([...currentVariant, currentElement]);
}
currentIndex++;
if (sumWithCurrent < number) {
findComponents(currentIndex, [...currentVariant, currentElement]);
}
}
}
findComponents();
return allVariants;
}
But I wonder if it's possible to use tail recursion for that? I have no idea how to turn my solution into tail recursion.
To make this tail recursive, you could:
Keep track of all indices that were selected to arrive at the current sum. That way you can easily replace a selected index with the successor index.
In each execution of the function get the "next" combination of indices. This could be done as follows:
If the sum has not been achieved yet, add the index the follows immediately after the most recently selected index, and adjust the sum
If the sum has achieved or exceeded, remove the most recently selected index, and then add the successor index instead, and adjust the sum
If there is no successor index, then forget about this index and replace the previous one in the list, again adjusting the sum
If there are no more entries in the list of indices, then all is done.
Instead of accumulating a sum, you could also decrease the number that you pass to recursion -- saving one variable.
Make the function return the array with all variants, so there is no need for an inner function, nor any action that follows the function call.
Here is an impementation:
function getNumberComponents(numArray, number, selectedIndices=[], allVariants=[]) {
let i = selectedIndices.at(-1)??-1;
if (number < 0) { // Sum is too large. There's no use to adding more
i = numArray.length; // Force the while-condition to be true
} else if (number == 0) { // Bingo
allVariants.push(selectedIndices.map(idx => numArray[idx]));
}
while (++i >= numArray.length) { // No more successor index available
if (selectedIndices.length == 0) return allVariants; // All done
i = selectedIndices.pop(); // Undo a previous selection
number += numArray[i]; // Remove from sum
}
selectedIndices.push(i); // Select index and recur:
return getNumberComponents(numArray, number - numArray[i], selectedIndices, allVariants);
}
console.log(getNumberComponents([7, 4, 3, 2, 5, 6, 8, 1], 8));
Here is my version of your function, but using tail recursion. This is still a complex subject for me, check if there are no mistakes
function getNumberComponents(numArray, number, currentIndex = 0, currentVariant = [], allVariants = new Set()) {
if (currentIndex >= numArray.length) {
const currentSum = currentVariant.reduce((acc, cur) => acc + cur, 0);
if (currentSum === number) {
allVariants.add(currentVariant);
}
return Array.from(allVariants);
}
const currentElement = numArray[currentIndex];
const currentSum = currentVariant.reduce((acc, cur) => acc + cur, 0);
const sumWithCurrent = currentSum + currentElement;
if (sumWithCurrent <= number) {
allVariants = new Set([...allVariants, ...getNumberComponents(numArray, number, currentIndex + 1, [...currentVariant, currentElement], allVariants), ...getNumberComponents(numArray, number, currentIndex + 1, currentVariant, new Set())]);
} else {
allVariants = new Set([...allVariants, ...getNumberComponents(numArray, number, currentIndex + 1, currentVariant, new Set())]);
}
return Array.from(allVariants);
}
console.log(getNumberComponents([7, 4, 3, 2, 5, 6, 8, 1], 8));
First off, here's the algorithm:
var removeDuplicates = function(nums) {
for (var i = 0; i < nums.length;) {
if (nums[i] === nums[i + 1]) {
nums.splice(i, 1)
}
else i++
}
return nums
};
It takes in a sorted array of numbers and removes any duplicates to return the original array modified to only include unique numbers.
My question mainly concerns the usage of the for loop. In this for loop we are omitting the third statement and instead are incrementing i in the else condition.
How does the loop know to check the next index of nums if the if condition is fulfilled? Ie. if we never hit else, how is i incremented? Is it even incremented? I understand this may have something to do with the fact that we are splicing (therefore shortening) the nums array in the if condition but I am having a hard time fully grasping why the loop does not end as soon as the if statement is fulfilled once.
When you do
nums.splice(i, 1)
this removes 1 item from the array at index i. For example, if i is 2, and the current array is
[0, 1, 2, 2, 3, 4]
then, right after that splice occurs, the array becomes
[0, 1, 2, 2, 3, 4]
^^ REMOVED: Array mutates to
[0, 1, 2, 3, 4]
The item that used to be at index i + 1 is now at index i, so the next iteration of the for loop should not increment i.
If you did increment i regardless, then every item that comes immediately after a removed item would be skipped, and not iterated over at all:
var removeDuplicates = function(nums) {
for (var i = 0; i < nums.length; i++) {
if (nums[i] === nums[i + 1]) {
nums.splice(i, 1)
}
}
return nums
};
console.log(removeDuplicates([0, 1, 1, 1]));
Still, this style of code is very confusing: when an object changes while you're iterating over it, it can be pretty unclear what the logic being implemented in accomplishes. Better to deduplicate via a Set:
var removeDuplicates = nums => [...new Set(nums)];
console.log(removeDuplicates([0, 1, 1, 1]));
I have six integers stored in an array:
[2,3,4,5,6,7]
I would like to use each item in the array to check against a range of other integers 100 - 999 (i.e. all three-digit numbers) to find a number that has a remainder of 1 when divided by all the items in the array individually.
I'm not sure what javascript method to use for this. I'm trying a for loop:
function hasRemainder() {
let arr = [2,3,4,5,6,7];
for (i = 100; i < 999; i++) {
if (i % arr[0] == 1) {
return i;
}
}
}
but it has several problems I need to solve.
Instead of referring to a particular item e.g. arr[0], I need to find a way to loop through all the items in the array.
Currently, this function only returns one number (the loop stops at the first number with a remainder), but I need all the possible values in the given range.
If anyone could help with these two problems, I'd really appreciate it. Thanks.
You could map an array of values and then filter the array by checking every remainder value with one.
function hasRemainder() {
var array = [2, 3, 4, 5, 6, 7];
return Array
.from({ length: 900 }, (_, i) => i + 100)
.filter(a => array.every(b => a % b === 1));
}
console.log(hasRemainder())
This works also;
function hasRemainder() {
const arr = [2, 3, 4, 5, 6, 7];
const remainders = []
for (i = 100; i < 999; i++) {
const isRemainder = arr.every(numb => i % numb === 1)
if (isRemainder) {
remainders.push(i)
}
}
return remainders
}
I have a question about feasibility of my code. I'm sure there is a better and more efficient way to write the function I wrote.
This is the function:
let i;
for (i = 0; i < ns.length; i++) {
if (ns[i] > 1) {
ns[i] = 3;
const place = ns[i];
ns.splice(place + 2, 1, 4);
ns.splice(place, 1, 2);
ns.splice(place - 1, 1, 1);
}
}
Initial Array (this array have a length of upto 20 items):
ns = [1 , 1 , 1 , 1 , 2 , 0]
Result Array:
ns = [1 , 1 , 1 , 2 , 3 , 4]
Believe it or not but this will suit my needs. But is there a better way than to just add up three times splice? It also extends my array if the number two of the initial array is at the end or beginning. I know I could just wrap it in another conditional but this seems so clumsy to me.
Thanks in Advance!
Regards
You could replace splicing with deleting a single value and adding a single value with a simple assingment at the index.
For preventing updating values at not given indices, you could take a function which checks the wanted index and updates only given indices.
function update(array, index, value) {
if (index >= 0 && index < array.length) {
array[index] = value;
}
}
var ns = [1, 1, 1, 1, 2, 0],
length = ns.length,
i,
place = 3;
for (i = 0; i < length; i++) {
if (ns[i] > 1) {
ns[i] = place;
update(ns, place - 1, 1);
update(ns, place, 2);
update(ns, place + 2, 4);
}
}
console.log(ns);
So with help from Nina Scholz and a Friend i got to the right answer:
Initial Array:
["1", "1", "1", "1", "1", "2", "0", "0"]
Desired Array:
["1", "1", "1", "1", "2", "3", "4", "0"]
The Function:
isSibling() {
const siblings = this.props.data.map(item => (
item.progress
));
let i;
const place = '3';
for (i = 0; i < siblings.length; i++) {
if (siblings[i] === '2') {
const num = i;
siblings[i] = place;
this.update(siblings, i - 1, '2');
this.update(siblings, i + 1, '4');
return siblings;
}
}
return siblings;
}
Update Function:
to ensure the array is not enlongated or shortened:
update(array, index, value) {
if (index >= 0 && index < array.length) {
array[index] = value;
}
}
Thank you for your help! :D
I need to create some sort of pattern of skips that I will set onto an array with the ability to choose which item of the array will be the first item of this "pattern" of skips and then return the items chosen by the pattern.
For example, I need to jump 2 2 1 2 in this arr = [1,2,3,4,5,6,7,8,9] so if its the second item (2) it will return [2,4,6,7,9] does anybody knows a way in JS to do this??
Try it
var original = [1,2,3,4,5,6,7,8,9];
var pattern = [2,2,1,2];
console.log(cutArray(original, pattern));
function cutArray(originalArray, jumpPatternArray){
for(var i = 0; jumpPatternArray.length > i; i++)
originalArray.splice(i, jumpPatternArray[i] - 1);
return originalArray;
}
Arrays are usually zero-indexed so saying the start index is two corresponds to the second element in the array is a bit odd, but something like this should get you started.
function skip (start, pattern, arr)
{
let idx = 0,
res = [ ];
pattern.unshift (start == 0 ? start : start - 1); // A bit odd but to accomodate the 1st index in the array being called the second element. You can just make this pattern.unshift (start); if you want to do it normally :)
for (let i of pattern) {
idx += i;
res.push (arr [idx]);
}
return res;
}
will give:
=> skip (2, [ 2, 2, 1, 2 ], [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]);
[ 2, 4, 6, 7, 9 ]