My apologies if this is a duplicate, I couldn't find an answer after searching for a while on Stackoverflow.
I am trying to use a nested loop to find any duplicate characters in a string.
So far, all I can manage to do is to find one duplicate the string.
For example, when I try the string "aabbcde", the function returns ['a', 'a'], whereas I was expecting ['a', 'a', 'b', 'b'].
I obviously have an error in my code, can anybody help point me towards what it could be?
const myStr = "aabbcde";
function duplicateCount(text){
const duplicates = [];
for (let i = 0; i < text.length; i++) {
for (let j = 0; j < text[i].length; j++) {
if (text[i] === text[j]) {
duplicates.push(text[i]);
}
}
}
return duplicates;
}
duplicateCount(myStr);
It should be something like this.
issues in this loop for (let j = 0; j < text[i].length; j++)
const myStr = "aabbcde";
function duplicateCount(text){
const duplicates = [];
for (let i = 0; i < text.length; i++) {
for (let j = i+1; j < text.length; j++) {
if (text[i] === text[j]) {
duplicates.push(text[i]);
}
}
}
return duplicates;
}
console.log(duplicateCount(myStr));
Using nested loop will make it very hard to do it,we can use a Object to store the appear count,and then filter the count
const myStr1 = "aabbcde";
const myStr2 = "ffeddbaa";
const duplicateCount = str => {
let map = {}
for(c of str){
map[c] = (map[c]??0) + 1
}
let result = []
for(m in map){
if(map[m] <= 1){
continue
}
result.push(...Array(map[m]).fill(m))
}
return result
}
console.log(duplicateCount(myStr1))
console.log(duplicateCount(myStr2))
You can simply achieve the result you're looking for by creating an object map of the string (meaning each key of the object will be each unique character of the string and their associated values will be the number of times each character is repeated in the string).
After you create an object map of the string, you can loop through the object and check if each value is greater than one or not. If they're you would push that item into a result array by the number of times the character is repeated. Please find my code here:
const myStr = 'aabbcde';
const duplicateCount = (str) => {
const result = [];
const obj = {};
str.split('').map((char) => {
obj[char] = obj[char] + 1 || 1;
});
for (key in obj) {
if (obj[key] > 1) {
for (let i = 0; i < obj[key]; i++) {
result.push(key);
}
}
}
return result;
};
console.log(duplicateCount(myStr));
I am working on an Advent Code Challenge and have run into a hall. I solved this error before, but in this instance, I am stuck. The following code is giving me a Uncaught TypeError: Cannot read properties of undefined. in relation to switch (diagArray[i][j]).
My thought is that diagArray is out of scope. Is that true?
Please, any help is great!
const diagArray = [
[0,1,0,0,0,1,1,1,0,0,0,1],
[1,1,0,1,0,0,0,0,0,0,0,1],
[1,1,1,0,0,1,0,0,1,0,1,1]
]; // example data
for(let i = 0; i < diagArray.length; i++) {
for (let j = 0; j < diagArray.length; i++) {
let gammaRate = ''
let epsilonRate = ''
let ones = 0
let zeros = 0
let rates = []
switch (diagArray[i][j]) {
case 1:
ones++
break
case 0:
zeros++
break
default:
break
}
if (ones > zeros) {
gammaRate+=1
epsilonRate+=0
} else {
gammaRate+=0
epsilonRate+=1
}
rates.push([gammaRate, epsilonRate])
// console.log(rates)
}
}
for(let i = 0; i < diagArray.length; i++) {
for (let j = 0; j < diagArray.length; i++) {
This here has multiple problems.
The first for loop is fine, but the second one needs be bounded by the length of the inner array:
diagArray[i].length
And it's also currently incrementing the first loops counts with i++. That needs to be j++
Working example:
const diagArray = [
[0,1,0,0,0,1,1,1,0,0,0,1],
[1,1,0,1,0,0,0,0,0,0,0,1],
[1,1,1,0,0,1,0,0,1,0,1,1]
]; // example data
for (let i = 0; i < diagArray.length; i++) {
for (let j = 0; j < diagArray[i].length; j++) {
let gammaRate = ''
let epsilonRate = ''
let ones = 0
let zeros = 0
let rates = []
switch (diagArray[i][j]) {
case 1:
ones++
break
case 0:
zeros++
break
default:
break
}
if (ones > zeros) {
gammaRate+=1
epsilonRate+=0
} else {
gammaRate+=0
epsilonRate+=1
}
rates.push([gammaRate, epsilonRate])
console.log(rates)
}
}
Also it's usually not advisable to have loops like this for iterating arrays, since, as you've discovered, it's very easy to screw up the indices.
I recommend interating over the values of the arrays instead:
for (const row of diagArray) {
for (const value of row) {
const diagArray = [
[0,1,0,0,0,1,1,1,0,0,0,1],
[1,1,0,1,0,0,0,0,0,0,0,1],
[1,1,1,0,0,1,0,0,1,0,1,1]
]; // example data
for (const row of diagArray) {
for (const value of row) {
let gammaRate = ''
let epsilonRate = ''
let ones = 0
let zeros = 0
let rates = []
switch (value) {
case 1:
ones++
break
case 0:
zeros++
break
default:
break
}
if (ones > zeros) {
gammaRate+=1
epsilonRate+=0
} else {
gammaRate+=0
epsilonRate+=1
}
rates.push([gammaRate, epsilonRate])
console.log(rates)
}
}
Your second iteration was increasing the i variable instead of j while iterating to the length of diagArray instead of diagArray[i].
You can use the Console API to debug your values to find out where the issue originates from without having to guess.
const diagArray = [
[0,1,0,0,0,1,1,1,0,0,0,1],
[1,1,0,1,0,0,0,0,0,0,0,1],
[1,1,1,0,0,1,0,0,1,0,1,1]
]; // example data
for(let i = 0; i < diagArray.length; i++) {
for (let j = 0; j < diagArray[i].length; j++) {
let gammaRate = ''
let epsilonRate = ''
let ones = 0
let zeros = 0
let rates = []
console.log(`${i}:${j} = ${diagArray[i][j]}`)
switch (diagArray[i][j]) {
case 1:
ones++
break
case 0:
zeros++
break
default:
break
}
if (ones > zeros) {
gammaRate+=1
epsilonRate+=0
} else {
gammaRate+=0
epsilonRate+=1
}
rates.push([gammaRate, epsilonRate])
// console.log(rates)
}
}
It's because in the second for loop it says diagArray.length, and it should be diagArray[i].length so that you are getting the length of the second array.
You should update the second for loop expression like this.
for (let j = 0; j < diagArray[i].length; j++) {
I have a data like below
data = ["I253,J665,l2575"]
and I need the the results like
I253,
J665,
l2575
when i tried to use for in i am getting like I253,J665,l2575 and I tried for loops also but not getting the result
let data = ["I253,J665,l2575"]
for (let i = 0; i > this.data.length; i++) {
console.log(i)
}
for (let x of this.data) {
console.log(x)
}
tried converting the data in to string and then using split changed into array but then also i am getting typeof object only
below is my stack blitz url =: https://stackblitz.com/edit/angular-ivy-drf1dk?file=src/app/app.component.ts
Modify your data variable like below:
data = ["I253", "J665", "l2575"];
for(let i = 0; i < this.data.length; i++){
console.log(this.data[i]);
}
If you have data variable as data = ["I253,J665,l2575"];
Then split it first and then loop through the generated array:
const arr = data[0].split(',');
for(let i = 0; i < arr.length; i++){
console.log(arr[i] + ',');
}
You were having multiple mistakes. First one was with for condition it should be i < this.data.length not i > this.data.length. Then you need to split and loop over it with for (let j = 0; j < data[i].split(',').length; j++) so data[i].split(',')[j] will return expected value.
In case of 2nd for...of loop you were simply logging whole value. Here also you need to split inside for...of and use one more loop to log.
Alternatively you can also use flatMap and loop over it like for (let m of data.flatMap(x => x.split(','))).
Try it below. You can use this.data, but it won't work in below example so it is used as simply data.
let data = ["I253,J665,l2575"];
console.log("Using for loop");
for (let i = 0; i < data.length; i++) {
for (let j = 0; j < data[i].split(',').length; j++) {
console.log(data[i].split(',')[j]);
}
}
console.log("Using for...of loop");
for (let x of data) {
for (let y of x.split(',')) {
console.log(y);
}
}
console.log("Using flatMap");
for (let m of data.flatMap(x => x.split(','))) {
console.log(m);
}
Two ways to solve this.
Also note that your loop is wrong SHOULD NOT BE '>' and Should Be '<'
1. Your data is at array index zero so if you are to keep the data as is
let data = ["I253,J665,l2575"]
let splits = data[0].split(',')
for (let i = 0; i < splits.length; i++) {
console.log(splits[i])
}
or
let data = ["I253,J665,l2575"]
let splits = data[0].split(',')
for (let element of splits) {
console.log(element )
}
2. Fix the data string
let dataString = "I253,J665,l2575"
let splits = dataString.split(',')
for (let i = 0; i < splits.length; i++) {
console.log(splits[i])
}
or
let dataString = "I253,J665,l2575"
let splits = dataString.split(',')
for (let element of splits) {
console.log(i)
}
Clone of the example provided in question
https://stackblitz.com/edit/angular-ivy-izj7up
I have trouble understanding nested for loops
posts: [
{
title: 'lorem',
comments: [
{
content: 'lorem'
user: 'John'
},
...
]
},
...
]
My goal here is to get all the comments from a specific user, in all the posts.
Here is how I proceed (I'm using mongoose, I get the user from an auth middleware)
const postsList = await Post.find();
var userComments = [];
for (var i = 0; i < postsList.length; i++) {
if (postsList[i].comments.length > 0) {
for (var j = 0; j < postsList[i].comments[j].length; i++)
if (postsList[i].comments[j].user == req.user.id) {
userComments.push(comments[j]);
}
}
}
When I try this, I get a Cannot read property 'length' of undefined. I think my error is in the second for loop, but I can't get why. Any help please?
Mark Meyer in the comments is correct.
comments is an array inside of each post object. comments[j] would refer to an element inside the comments array. comments[j].length doesn't make sense because in order to run your nested j for loop, which iterates over the comments array, you want the length of the comments array, not the length of one of its elements.
Here's the line that needs to be fixed:
const postsList = await Post.find();
var userComments = [];
for (var i = 0; i < postsList.length; i++) {
if (postsList[i].comments.length > 0) {
// for (var j = 0; j < postsList[i].comments[j].length; i++)
// fixed version below
for (var j = 0; j < postsList[i].comments.length; i++)
if (postsList[i].comments[j].user == req.user.id) {
userComments.push(comments[j]);
}
}
}
I am trying to update a specific array index with a new carrier_id and name.
However, I'm getting a puzzling assignment problem.
Comment line with Note #1 out and nData will look fine, otherwise its order property appears to get set before updateNormalizedData is called.
let data = JSON.parse('[{"order":{"po_no":"po_2019","ship_details":{"carrier_id":1044777,"method":"FREE Shipping"},"sub_total":0},"items":[{"header":{"set_no":0,"carrier_id":104777,"po_no":"po_2019"},"line":{"item_id":"ABC RE1000","line_no":0}},{"header":{"set_no":0,"carrier_id":104777,"po_no":"po_2019"},"line":{"item_id":"ABC DA1111","line_no":1}}]}]');
let numSet = 0;
let numLine = 1;
let args = {"carrier_id": 555111};
function normalizeData(data, numSet, numLine, args) {
let i = 0, j = 0, l = data.length;
let normalizedDataSet = [];
// console.log(data[i])
for (i = 0; i < l; i++) {
let m = data[i]['items'].length;
for (j = 0; j < m; j++) {
data[i]['items'][j]['order'] = { ...data[i]['order'] }; // Destructure data to assign value, not object reference
normalizedDataSet.push(data[i]['items'][j]);
}
}
// console.log('nData', normalizedDataSet);
updateNormalizedData(normalizedDataSet, numSet, numLine, args); // Note #1
}
function updateNormalizedData(normalizedDataSet, numSet, numLine, args) {
let i;
let n = normalizedDataSet.length;
let newNormal = [];
for (i = 0; i < n; i++) {
let index = { ...normalizedDataSet };
if (numSet === index[i]['header']['set_no'] && numLine === index[i]['line']['line_no']) {
let shipMethods = JSON.parse('[{"id":103366,"name":"FREE Shipping"},{"id":200200,"name":"BEST"},{"id":555111,"name":"COLLECT"}]');
let shipMethod = shipMethods.filter(item => { return item.id === args.carrier_id }); // [0]['name'];
console.log("date_updated this index", i);
index[i]['order']['ship_details']['carrier_id'] = args.carrier_id;
index[i]['order']['ship_details']['method'] = shipMethod[0]['name'];
newNormal.push(index[i]); // Should update order.ship_details.carrier_id
} else {
console.log("Use original index");
newNormal.push(normalizedDataSet[i]); // Should NOT update order.ship_details.carrier_id
}
}
console.log('new normal', JSON.stringify(newNormal));
}
normalizeData(data, numSet, numLine, args);
I'm not sure how the property is getting assigned "before" a function is called that assigns it.
I'm guessing it may have something to do with the data destructuring, but I'm not certain.
Any guidance / help is greatly appreciated.
In this example I'm trying to update just { "setNo": 0, "lineNo": 1 } with new normal order data, but both lines 0 and 1 are being set.