I'm building up an array of socket.ids and trying to get a 'temporary' id for them by getting the array index as being the 'temporary' ID.
I am currently building my array as follows:
let serving_point_key = serving_points.indexOf(socket.id);
if (serving_point_key === -1) {
serving_points.push(socket.id);
serving_point_key = serving_points.indexOf(socket.id);
}
let serving_point_id = serving_point_key + 1;
and I am removing the items from the array as:
let serving_point_key = serving_points.indexOf(socket.id);
if (serving_point_key !== -1) {
serving_points.splice(serving_point_key, 1);
}
The issue I'm having is that if there is 3 items in the array, and I remove the second for example, the index of the third item is now 1 less, therefore the logic of using indexOf to get an 'temporary' ID is flawed when I try and get the "ID" for the socket user as it's changed as soon as I remove an item before it in the array?
Is there anyway to keep the index when I push to an array, so that the index is kept when removing? maybe using a multi dimensional array? or would it be best to use objects?
Any help or advice would be greatly appreciated.
I've updated the logic to push an object to the array and store the ID.
let serving_point_key = serving_points?.findIndex(sp => sp.socket_id === socket.id);
if (serving_point_key === -1) {
let id = null;
if (serving_points.length === 0) {
id = 1;
} else {
for( var i = 0; i < serving_points.length; i++ ) {
let id_exists = (serving_points?.findIndex(sp => sp.id === (i + 1)) !== -1);
if (id_exists === false) {
id = (i + 1);
}
}
console.log(id);
if (id === null) {
id = serving_points.length + 1;
}
}
let sp_data = {
'id': id,
'socket_id': socket.id
}
serving_points.push(sp_data);
serving_point_key = serving_points?.findIndex(sp => sp.socket_id === socket.id);
}
let serving_point_id = serving_points[serving_point_key].id;
I'm trying to create a function which returns me halve the data sumed up. I was able to do it on a non-nested Array but failing on the nested Array. I get the error Cannot read properties of undefined (reading 'push').
How the returned data should look like:
var data = [{"Key":1,"values":[
{"LastOnline":"21-11-29","Value":2},
{"LastOnline":"21-12-01","Value":2},
{"LastOnline":"21-12-03","Value":2}
]}];
What I have right now:
var data = [{"Key":1,"values":[
{"LastOnline":"21-11-28","Value":1},
{"LastOnline":"21-11-29","Value":1},
{"LastOnline":"21-11-30","Value":1},
{"LastOnline":"21-12-01","Value":1},
{"LastOnline":"21-12-02","Value":1},
{"LastOnline":"21-12-03","Value":1},
]}];
function halveMonth(data){
var newData = [];
var temp = [{"key":data.key,"values":[{}]}];
// sum 2 togheter
for(var i=1;i<data.values.length;i++){
if(data.values[i]){
temp.values[i].push({"LastOnline":data.values[i].LastOnline, "Value":(data.values[i].Value + data.values[[i-1]].Value)});
}
}
for(var i=0;i<temp.values.length;i++){
if(i % 2 == 0){
newData.push(temp.values[i]);
}
}
return newData;
}
console.log(halveMonth(data));
JS variables are case sensitive. Keep the key consistent everywhere. If you don't plan to use reduce here is the solution.
var data = [{"key":1,"values":[
{"LastOnline":"21-11-28","Value":1},
{"LastOnline":"21-11-29","Value":1},
{"LastOnline":"21-11-30","Value":1},
{"LastOnline":"21-12-01","Value":1},
{"LastOnline":"21-12-02","Value":1},
{"LastOnline":"21-12-03","Value":1},
]}];
function halveMonth(data){
let newData = []
for (let i = 0; i < data.length; i++) {
let temp = {"key":data[i].key,"values":[]}
for (let j = 0; j < data[i].values.length; j += 2) {
const res = (j+1===data[i].values.length) ? data[i].values[j].Value : data[i].values[j].Value + data[i].values[j+1].Value
temp.values.push({"LastOnline":(j+1===data[i].values.length)?data[i].values[j].LastOnline:data[i].values[j+1].LastOnline,"Value":res});
}
newData.push(temp);
}
return newData
}
console.log(halveMonth(data));
The variable data you declare at the first line of your snippet is an array. So you can't do data.values. You first need to indicate which index of your array you want to read. In this case : data[0].values
First things first, you data is itself an array - so assuming your real data has more than 1 element you'll need to do the same thing for each one.
It's helpful to start off with a method which does the work on just 1 element
const justASingle = {"Key":1,"values":[{"LastOnline":"21-11-28","Value":1},{"LastOnline":"21-11-29","Value":1},{"LastOnline":"21-11-30","Value":1},{"LastOnline":"21-12-01","Value":1},{"LastOnline":"21-12-02","Value":1},{"LastOnline":"21-12-03","Value":1}]};
function halveMonthSingle(data) {
return {
...data,
values: data.values.reduce((acc, item, idx) => {
if ((idx % 2) != 0)
acc.push({
...item,
Value: data.values[idx - 1].Value + item.Value
})
return acc;
}, [])
}
}
console.log(halveMonthSingle(justASingle))
Once you have that you can just use map do do it for every element
const data = [{"Key":1,"values":[{"LastOnline":"21-11-28","Value":1},{"LastOnline":"21-11-29","Value":1},{"LastOnline":"21-11-30","Value":1},{"LastOnline":"21-12-01","Value":1},{"LastOnline":"21-12-02","Value":1},{"LastOnline":"21-12-03","Value":1}]}];
function halveMonthSingle(data) {
return {
...data,
values: data.values.reduce((acc, item, idx) => {
if ((idx % 2) != 0)
acc.push({
...item,
Value: data.values[idx - 1].Value + item.Value
})
return acc;
}, [])
}
}
const result = data.map(halveMonthSingle)
console.log(result)
I would use reduce - saves me from trying to figure out why your two loops do not work other than data.values should be data[0].values
var data = [{"Key":1,"values":[{"LastOnline":"21-11-28","Value":1},{"LastOnline":"21-11-29","Value":1},{"LastOnline":"21-11-30","Value":1},{"LastOnline":"21-12-01","Value":1},{"LastOnline":"21-12-02","Value":1},{"LastOnline":"21-12-03","Value":1},]}];
const newArr = data.slice(0); // to not mutate original
newArr[0].values = data[0].values.reduce((acc,item,i) => {
if (i%2 !== 0) { // every second
acc.push(data[0].values[i]); // push the item
acc[acc.length-1].Value += data[0].values[i-1].Value; // add the first
}
return acc
},[])
console.log(newArr)
This works too. I basically did your idea, skipping the temp array and merging the two steps into one.
const data = [{"Key":1,"values":[
{"LastOnline":"21-11-28","Value":1},
{"LastOnline":"21-11-29","Value":1},
{"LastOnline":"21-11-30","Value":1},
{"LastOnline":"21-12-01","Value":1},
{"LastOnline":"21-12-02","Value":1},
{"LastOnline":"21-12-03","Value":1},
]}];
function halveMonth(data) {
const newData = [];
newData.push({
Key: data[0].Key,
values: []
});
for(let i = 0; i < data[0].values.length; i++){
if (i % 2 !== 0) {
newData[0].values.push({
LastOnline: data[0].values[i].LastOnline,
Value: data[0].values[i].Value + data[0].values[i-1].Value
});
}
}
return newData;
}
console.log(halveMonth(data));
I am trying to compare two arrays( containing 3 integers) and return a hint message array that conform to the logic
-Push “Almost” when 1 digit and position match in array
-push “not quite” when 1 digit matches but different position
-push “incorrect “ when no digits match
push “correct” When exact match
Example of arrays :
Array1 = [2,7,6]
ReferenceArray= [2,9,7]
Hint= [“Almost”, “Not Quite”];
Code I have so far:
function check( array1, referenceArray ) {
let hint=[];
for(i=0;i<referenceArray.length;i++){
for (j=0;j<Array1.length;j++){
//value and position match
if ((referenceArray[i] && reference.indexOf[i]) === (Array1[j] && Array1.indexOf[j])) {
return hint.push('almost');
}
//value matches but not position
else if(( referenceArray[i] ===Array1[j]) && !(referenceArray.indexOf[i]===Array1.indexOf[j] )){
return hint.push('not quite');
}
}// end of Array1 iteration
} // end of reference interation
// if all values and position match
if(referenceArray===Array1){
return hint.push("correct");
}
//if no values match
else if (referenceArray!==Array1){
return hintArray.push("incorrect");
}
I would use some built in Array methods to help achieve this: every(), map() and findIndex().
I generally avoid using .push() because it mutates the array. Immutable code is nice to read 😉
const check = (array, referenceArray) => {
if (array.every((val, index) => val === referenceArray[index] )) {
return ['Correct']
}
const allHints = array.map((val, index) => {
const refArrayIndex = referenceArray.findIndex(refVal => val === refVal);
if (refArrayIndex === index) {
return 'Almost'
}
if (refArrayIndex !== -1) {
return 'Not Quite'
}
return undefined
});
const hints = allHints.filter((hint) => hint !== undefined);
if (hints.length > 0) {
return hints;
}
return ['Incorrect']
};
const hints = check([2,7,6],[2,9,7]);
console.log('hints', hints)
I did this code, tell me if it works or not 😁
const array1 = [2,7,6]
const ReferenceArray = [2,9,7]
function compareArrays(arr){
let perfect = true
for(let i = 0; i < ReferenceArray.length; i++){
if(ReferenceArray[i] != arr[i]) {
perfect = false
break
}
}
if(perfect) return 'correct'
let hint = []
for(let i = 0; i < ReferenceArray.length; i++){
if(arr[i] == ReferenceArray[i]) hint.push('Almost')
else if(ReferenceArray.includes(arr[i])) hint.push('Not Quite')
}
if(hint.length > 0) return hint
return 'incorrect'
}
console.log(compareArrays(array1))
I currently have a function below to find the first nonrepeating letter. For example, for the string carro, that letter would be c; for the string total, that letter would be o.
I have the following code that works:
function findFirstNonrepeatedChar(str) {
const store = {};
const arr = str.split('');
arr.forEach(item => {
if(!store[item]) {
store[item] = 1;
} else {
store[item] = store[item] + 1;
}
})
for(let char in store) {
if(store[char] === 1) return char;
}
}
However, now I want to use a Map instead of just a plain object, and I'm having difficulty to update the frequency of the duplicate word like below:
function findFirstNonrepeatedChar(str) {
const store = new Map();
const arr = str.split('');
arr.forEach(item => {
if(!store.has(item)) {
store.set(item, 1);
} else {
store[item]++;
}
})
console.log(store, 'store')
for(let char in store) {
if(store[char] === 1) return char;
}
}
What would be the best way to do so?
There are 2 things here:
you set to save the key-value to store, use get to get the value by key
store.set(item, (store.get(item) || 0) + 1);
you iterate the key-value pairs of Map by for..of, not for..in
function findFirstNonrepeatedChar(str) {
const store = new Map();
const arr = str.split("");
arr.forEach((item) => {
store.set(item, (store.get(item) || 0) + 1);
});
for (let [char, occurrences] of store) {
if (occurrences === 1) {
return char;
}
}
}
console.log(findFirstNonrepeatedChar("carro"));
console.log(findFirstNonrepeatedChar("total"));
Here's how I'd do it using Array.prototype.find() if you're interested in alternative solutions.
const findFirstNonrepeatedChar = (str) => str.split('').find(
(val) => str.match(new RegExp(val, 'g')).length === 1
);
console.log(findFirstNonrepeatedChar('total'));
console.log(findFirstNonrepeatedChar("carro"));
console.log(findFirstNonrepeatedChar("aabbcc"));
I am creating a project using Angular. During the development, I am facing a problem when pushing values to my array. My requirement is that I want to push the value to the array unless the value already exists in the array. If it already exists, then simply replace that value with newer value.
This is my code, which is currently not working:
var obj = {
question_id: "1",
id: "2",
"question": "This is a test"
};
This is the object that I want to push:
this.selectedOptions = [];
if (!this.selectedOptions.some(function(entry) { return entry.question_id === category.question_id;})) {
this.selectedOptions.push(category);
}
Your code will push the item to the array, but it won't replace an existing item.
I'm assuming that its an array of objects, given the entry.question_id part.
What you need is to check if the object exists in the array, and update or push it accordingly. The findIndex method will return the object index, if it exists in the array, or -1 if not.
const entryIndex = this.selectedOptions.findIndex(entry => entry.question_id === category.question_id);
if (entryIndex > -1) {
this.selectedOptions[entryIndex] = category;
} else {
this.selectedOptions.push(category);
}
You could find the index for update or push something new.
let index = this.selectedOptions.findIndex(function (entry) {
return entry.question_id === category.question_id;
});
if (index === -1) {
this.selectedOptions.push(category);
} else {
this.selectedOptions[index].someKey = 'someValue';
}
Try this:
function customUpsert(arr, data) {
const index = arr.findIndex((e) => e.id === data.id);
if (index === -1) {
arr.push(data);
} else {
arr[index] = data;
}
}
Following funcntion checks if "oldVal" exists and replace it with the "newVal" if it does.
var selectedOptions = [1, 2, 3];
function replaceOrAppend(oldVal, newVal) {
let idx = selectedOptions.indexOf(oldVal);
if (idx < 0)
selectedOptions.push(newVal)
else
selectedOptions[idx] = newVal;
}
replaceOrAppend(1, 100);
replaceOrAppend(10, 200);
console.log(selectedOptions);