add or push a 10th index number to the array - javascript

I was working on a chart where i need my data to be sliced into small object based for better visibility. My array that i have is
{
"size":[
{
"timestamp":"1641329889000",
"size":12345,
"fees":123456,
"cost":168
},
{
"timestamp":"1641387032",
"size":456789,
"fees":4567891,
"cost":249
},
{
"timestamp":"1641435786",
"size":98765,
"fees":987654,
"cost":987
},
{
"timestamp":"1641435786",
"size":98765,
"fees":987654,
"cost":987
},
{
"timestamp":"1641435786",
"size":98765,
"fees":987654,
"cost":987
}
]
}
in which i want the array to be in this form
{
"size":{
"timestamp": ["1641329889000","1641387032","1641435786"],
"size": [12345,456789,98765],
"fees": [123456,4567891,987654],
"cost": [168,249,987]
}
}
i can achieve this using foreach and push like this
result.forEach(element => {
this.state.timestamp.push(element.timestamp);
this.state.size.push(element.size);
});
But i want this array to have the items only from the 10,20,30,40th index alone
I want not all the value. the values should be chosen only in the basis of x+10
Could anyone help me on this

Instead of forEach why not just use a for loop, and on the condition use the modulus % operator with 10? Like if (i % 10 == 0) inside of the for loop, or just increment i by 10 like i+=10.

You could take a for loop and a step for incrementing the index.
const
step = 10,
keys = ["timestamp", "size", "fees", "cost"],
result = Object.fromEntries(keys.map(k => [k, []]));
for (let i = 0; i < size.lenght; i += step) {
keys.forEach(key => result[key].push(size[i][key]));
}

Using forEach is a waste of resources.
You can use for instead:
for(let i=0;i<result.length;i+10){
this.state.timestamp.push(result[i].timestamp);
this.state.size.push(result[i].size);
}
For setting the state you should use setState not just push to it.
let tmp = {
...this.state
}
for(let i=0;i<result.length;i+10){
tmp.size.timestamp.push(result[i].timestamp);
tmp.size.push(result[i].size);
}
this.setState(tmp)

As mentioned by #cybercoder, you probably don't want to change the state variable within the forEach, as that will cause render to be called excessively.
You could simply use a counter and only push elements when the index is divisible by 10:
let i = 0;
let {timestamp, size} = this.state;
result.forEach(element => {
if (i % 10 === 0) {
timestamp.push(element.timestamp);
size.push(element.size);
}
i++;
});
this.setState({
...this.state,
timestamp,
size
});
If you do not want to include the very first (index 0) element:
let i = 0;
let {timestamp, size} = this.state;
result.forEach(element => {
// Exclude very first element
if (i % 10 === 0 && i !== 0) {
timestamp.push(element.timestamp);
size.push(element.size);
}
i++;
});
this.setState({
...this.state,
timestamp,
size
});

Related

Element is not inserting into array in a loop and also looping twice JS/React

I try to insert a string into a particular index of object if condition is true inside a forloop but its not inserting of some reason. I tried to use push and append and splice but splice just inserting entire string as an new object into the array and i need it to just append to existing object. Any ideas how to make it work?
Data looks like that:
const [concerts, setConcerts] = useState([]);
const [tickets, setTickets] = useState([]);
const [limit, setLimit] = useState(25);
const navigate = useNavigate();
const [button, setButton] = useState(false);
const [array, setArray] = useState([]);
//Raw JSON Date example: "2023-02-08T23:15:30.000Z"
let currentDate = new Date().toJSON().slice(0, 10);
const json = { available: "true" };
useEffect(() => {
const loadConcerts = async () => {
const resConcerts = await axios.get("/data/concerts");
const resTickets = await axios.get("/data/tickets");
let table = [];
setTickets(resTickets.data);
// getting all concerts above today
const filteredData = resConcerts.data.filter((concert) => {
return concert.datum >= currentDate;
});
filteredData.forEach((element) => {
table.push(element);
// table.splice(10, 0, { status: "available" });
});
setArray(table);
for (let i = 0; i < resTickets.data.length; i++) {
for (let j = 0; j < filteredData.length; j++) {
if (
resTickets.data[i].concertid == filteredData[j].id &&
resTickets.data[i].booked == 0
) {
table.push({ status: "avaiable" });
// table.splice(10, 0, { status: "available" });
}
}
}
setArray(table);
// filteredData.forEach((concert) => {
// for (const ticket of tickets) {
// if (concert.id == ticket.concertid && ticket.booked == 0) {
// table.push(json);
// }
// }
// });
setConcerts(
filteredData.sort((a, b) =>
a.datum > b.datum ? 1 : a.datum < b.datum ? -1 : 0
)
);
};
console.log("from use effect: " + array.length);
loadConcerts();
}, []);
After using splice method:
Update
Problem is solved. I used Object.assign() helped to append string to existing object in array. Actually i had to insert another object, not a single variable.
The problem is you are trying to push a string "available" into an array-of-objects.
Here you see the object with a property datum:
const filteredData = resConcerts.data.filter((concert) => {
return concert.datum >= currentDate;
});
Yet below when you push, you are not pushing an object into the array which is problematic. It should probably be something like this but you have to verify:
Instead of this:
filteredData.push("available");
Domething like this:
filteredData.push({ datum: '', status: 'available' );
I don't know what your data object is but it's an object not a string you need to add to that array.
The looping twice is likely from React 18 New Strict Mode Behaviors. It intentionally unmounts/remounts components to fire your useEffect calls twice - so that you can identify problematic side effects. If you remove <StrictMode> or run in production that double-looping should not occur.
Problem solved. Push() neither splice() method didn't helped. What helped me to append my object to another object without changing the data was Object.assign() function
for (let i = 0; i < resTickets.data.length; i++) {
for (let j = 0; j < filteredData.length; j++) {
if (
resTickets.data[i].concertid == filteredData[j].id &&
resTickets.data[i].booked == 0
) {
Object.assign(filteredData[j], obj);
}
}
}

Checking for "triplicates" strings in JavaScript array

trying to find the best way to check for triplicates values inside an array of strings.
I found many stackoverflow solutions for duplicates values which is not the case in here.
This is the farest i could get with solving this and I am not sure if it is the correct way:
const array = [
"peace",
"peace",
"Vrede",
"Patz",
"Salam",
"paz",
"Salam",
"Salam"
];
const findTriplicates = (param) => {
let counts = {};
for (let i = 0; i < param.length; i++) {
if (counts[param[i]]) {
counts[param[i]] += 1;
} else {
counts[param[i]] = 1;
}
}
for (let i in counts) {
if (counts[i] === 3) {
console.log(i + " exists " + counts[i] + " times.");
}
}
};
findTriplicates(array); // Salam exists 3 times.
please don't hesitate to fix my code or to post your solution.
thanks for your support in advance :)
Cheerz!
Your overall idea is good, using Hash Maps (js objects) is the best option for the task.
You can move your "=== 3" check to the first loop and have another object to save triplicates, it will be twice faster.
check this out
const findTriplicates = (param) => {
let values = [...new Set(param)];
let triples = [];
values.forEach(item=>{
let counter = 0;
param.forEach(s=>{
if(s===item) counter++;
})
if(3==counter) triples.push(item);
})
return triples;
};
There is no correct way to do things like this. You can always optimize or sacrifice performance for readability, but that is up to the developer.
I changed nothing about the functionality in findTriplicates, but the code is very different.
findTriplicates2 works a little different but is by no means superior
const array = [
"peace",
"peace",
"Vrede",
"Patz",
"Salam",
"paz",
"Salam",
"Salam"
];
const findTriplicates = (param) => {
let counts = param.reduce((acc, p) => {
acc[p] ? acc[p]++ : acc[p] = 1
return acc;
}, {})
Object.keys(counts).forEach((key) => counts[key] === 3 &&
console.log(`${key} exists 3 times.`)
);
};
findTriplicates(array); // Salam exists 3 times.
const findTriplicates2 = (param) => {
let triples = [...new Set(param)].reduce((acc, item) => {
let counter = param.reduce((acc2, s) => {
if (s === item) acc2++;
return acc2;
}, 0);
if (3 == counter) acc.push(item);
return acc;
}, [])
triples.forEach((triple) => console.log(`${triple} exists 3 times.`));
};
findTriplicates2(array); // Salam exists 3 times.
You create an object to keep count of how many times the string repeats and then iterate through each element in the array while updating the count in the object. Then you filter through that object for any values equal to 3.
const array = [
'peace',
'peace',
'Vrede',
'Patz',
'Salam',
'paz',
'Salam',
'Salam',
];
// Object to keep count of each word
const countObj = {};
// Iterate through the array to get the count for each word
array.forEach((element) => {
// Does word exist in the count object? if so -> add 1 to its count, else -> add word and count 1 to the object
countObj[element] ? (countObj[element] += 1) : (countObj[element] = 1);
});
// Filter out keys that appear exactly 3 times and print them them
const filteredArray = Object.keys(countObj).filter(
(key) => countObj[key] === 3
);
console.log(filteredArray); // Salam

Array of strings randomly remove 3 and replace with “” but keep original indexes

const state = reactive({
verify: [
"brain",
"show",
"toy",
"him",
"aim",
"built",
"store",
"there",
"skim",
"wing",
"honest",
"try",
],
});
function remove(array: string[], numberOfDeletions: number) {
array = state.array;
for (var i = 0; i < numberOfDeletions; i++) {
array.splice(Math.floor(Math.random() * array.length), 1);
}
console.log(array);
}
onMounted(async () => {
const mnemonic = await removeRandomly(state.verify, 3);
});
function getWords(words: Array<string>) {
state.mnemonicPhrase = words;
}
this is removing 3 items and being replaced with "" but the changed indexes are being pushed to the last 3 indexes i need everything to stay in its original indexes and i cant seem to figure out whats going on here
also note that i have a ternary in my Vue code to change the value of props if the input is empty to return "" so i can visually see it is working that its being removed
Try this
for (var i = 0; i < numberOfDeletions; i++) {
arr.splice(Math.floor(Math.random() * arr.length), 1,"");
}

output element from the array with different index

I have a table. When I click on an element I return its index. How can I (starting from this element) display all elements with index + 9. i.e. if the selected element has index 0, then I also need to display elements with indexes 9, 18, 27, etc.
let newCell = [td#2, td#0, td#2, td#0, td#2, ..... td#1, td#0]
newCell.forEach((item, i) => {
item.addEventListener('click', () => {
console.log(i)
})
})
I have not included the code to "display" those elements that will come in the series, but below is the code that logs them out. You can update it to display them.
const DIFF = 9;
newCell.forEach((item, i) => {
item.addEventListener('click', ()=>logAllItemsInSeries(i));
}
const logAllItemsInSeries = (i) => {
console.log(i);
const series = [];
while (i < newCell.length) {
series.push(i);
i += DIFF;
}
series.forEach((index) => {
console.log(index);
console.log(newCell[index]);
});
};
What you need to do in this case is keep track of a count of what elements should be filtered out and then update that count as you filter through it. Unfortunately your cell data is unclear to me so I went ahead and made my own to explain.
let data = [];
for (let i = 0; i < 100; i++) {
data.push({ id: i });
}
function getByNine(id) {
let count = id + 9
return data.filter(i => {
if (i.id === count) {
count = count + 9
return i
} else {
return
}
})
}
console.log(getByNine(3))
Inside your event listener you would put a reference to the getByNine(i) function (or whatever you want to call it) and pass its index.
Inside this function you set a default count of 9 + whatever the id of the element clicked
Run a filter through your array of objects, when the count is correct return that item and then increment the count by 9 for the next correct element
function getByNine(i) {
// code here
}
newCell.forEach((item, i) => {
item.addEventListener('click', () => {
getByNine(i)
})
})

How can I check if a value exists in an array with multiple objects - javascript?

So my array looks like this:
let array = [
{"object1":1},
{"object2":2},
{"object3":3}
];
What I want to do is to check, for example, whether or not "object1" exists. The way I would prefer is pure Javascript.
I am doing this for large chunks of data and so my code needs to be something like this:
if ("opensprint1" in array){
console.log("yes, this is in the array");
} else {
console.log("no, this is not in the array");
};
NOTE: I have tried to use the (in) function in JS and the (hasOwnProperty) and neither has worked.
Any ideas?
if ("opensprint1" in array){
That check for the array keys, so it would work with:
if ("0" in array){
But actually you want to check if some of the array elements got that key:
if(array.some( el => "opensprint1" in el))
You're trying to filter an array of objects. You can pass a custom function into Array.prototype.filter, defining a custom search function. It looks like you want to search based on the existence of keys. If anything is returned, that key exists in the object array.
let array = [{
"object1": 1
},
{
"object2": 2
},
{
"object3": 3
}
];
const filterByKey = (arr, keyName) =>
array.filter(obj => Object.keys(obj).includes(keyName)).length > 0;
console.log(filterByKey(array, 'object1'));
console.log(filterByKey(array, 'object5'));
That is roughly equivalent to:
let array = [{
"object1": 1
},
{
"object2": 2
},
{
"object3": 3
}
];
const filterByKey = (arr, keyName) => {
// iterate each item in the array
for (let i = 0; i < arr.length; i++) {
const objectKeys = Object.keys(arr[i]);
// take the keys of the object
for (let j = 0; j < objectKeys.length; j++) {
// see if any key matches our expected
if(objectKeys[i] === keyName)
return true
}
}
// none did
return false;
}
console.log(filterByKey(array, 'object1'));
console.log(filterByKey(array, 'object5'));
This might help you
let array = [
{"object1":1},
{"object2":2},
{"object3":3}
];
let targetkey = "opensprint1";
let exists = -1;
for(let i = 0; i < array.length; i++) {
let objKeys = Object.keys(array[i]);
exists = objKeys.indexOf(targetkey);
if (exists >= 0) {
break;
}
}
if (exists >= 0) {
console.log("yes, this is in the array");
} else {
console.log("no, this is not in the array");
}
let array = [
{ "object1": 1 },
{ "object2": 2 },
{ "object3": 3 }
];
let checkKey = (key) => {
var found = false;
array.forEach((obj) => {
if (!(obj[key] === undefined)) {
found = true;
array.length = 0;
}
});
return found;
}
console.log(checkKey("object2"));
In this case, I think one of the most efficient way is to do a for and break like:
let array = [
{"object1":1},
{"object2":2},
{"object3":3}
];
exist = false;
for(let i = 0; i<array.length; i++){
if("object1" in array[i]){
exist = true;//<-- We just know the answer we want
break;//<-- then stop the loop
}
}
console.log(exist);
When iteration finds a true case, stops the iteration. We can't perform a break in .map, .filter etc. So the number of iterations are the less possible. I think this is also the case of .some()

Categories