How to get access to the index in .find method - javascript

allPlans has an array of objects. The code below successfully finds the correct plan passed if _plan.name( of find method) matches this.click_Plan.
Right below it I need the value of the index of that plan and assign it here in place of index. I initially did it using for loop but I am trying to do the same with .find.
this.currentSection = 'Section'+index;
Also I need to be sure than the above statement always runs after the find is completed, do I need a call back in this case ?
And why doesn't this syntax work is that not an arrow function ?
this.plan = this.allPlans.find((_plan: any) => { _plan.name === this.clicked_plan });
.
this.plan = this.allPlans.find((_plan: any) => _plan.name === this.clicked_plan);
this.currentSection = 'Section'+index;
console.log(this.plan);

Use .findIndex instead, to get the index only initially, then select the value at the index afterwards:
const foundIndex = this.allPlans.findIndex((_plan: any) => _plan.name === this.clicked_plan);
this.plan = this.allPlans[foundIndex];
this.currentSection = 'Section'+foundIndex;

Use findIndex(). It totally works as find() but instead of returning the value it will return index of the element
var a=[1,2,3,4,5,6]
function s(e)
{
if(e==2)
return e
}
console.log(a.findIndex(s)) //returns 1 which is index of element 2 in the array

Related

Use a filter in typescript array to get a value of the first node returned

I have an array coming in that can be filtered but sometimes it will return no results after the filter and other times 1 result, which is the one I need.
It goes something like this:
this.outArray.variableTest = inArray.info.filter(q => (q.myId=== TestIdTypes.FirstId)[0].name;
The problem is that the filter can be undefined if nothing is matched, causing an exception. If something matches then [0].name is correct and what I want. How do I check if it has length 0 or undefined? I can use any other typescript code if needed.
You can use Array.prototype.find instead of filter and use the optional chaining operator.
const name = inArray.info.find(q => q.myId=== TestIdTypes.FirstId)?.name;
Just check if the resulting item is defined or not first:
const filtered = inArray.info.filter(q => q.myId=== TestIdTypes.FirstId);
if (filtered.length) {
this.outArray.variableTest = filtered[0].name;
}
But .find would really be more appropriate (and a bit more type-safe):
const found = inArray.info.find(q => q.myId === TestIdTypes.FirstId);
if (found) {
this.outArray.variableTest = found.name;
}

Returning foreach() function is undefined than the value itself

I have tried foreach function ,
it is returning undefined rather than the value itself. i have no clue where did i go wrong .
let value = Array.from(container).forEach((data) => {
if(data.innerText === titleID){
// -- when i console log this, it is returning the value i want
console.log(data.parentNode.parentNode.getElementsByClassName(kpiID)[0].innerText)
// -- here it is returning underfine
return data.parentNode.parentNode.getElementsByClassName(kpiID)[0].innerText;
}
});
value();
Based on my research,
Some say that we couldnt return value using foreach, some said its better to use filters. i am confuse which approach should i take. any advice? Thanks
This is because forEach does not return anything. It just iterates on the array.
Maybe you need a combination of Array.prototype.map and Array.prototype.filter?
let value = Array.from(container).map((data) => {
if (data.innerText === titleID) { console.log(data.parentNode.parentNode.getElementsByClassName(kpiID)[0].innerText)
return data.parentNode.parentNode.getElementsByClassName(kpiID)[0].innerText;
}
return false;
}).filter(el => el !== false);
Because the map will have some falsy values for the elements which doesnt suffice the if-condition. So, you need .filter to remove those elements.
If you want the value from forEach to be the element in a new array, what you're looking for is .map
let value = Array.from(container).map(function(data){...});
Whatever you return in .map will be the matching element in the new array value
You could create an async function where a Promise resovle the value instead of a return inside the forEach. Then await the value of the function.
This is one solution to get the result from the forEach.

How to calculate the number of objects I get from the loop Javascript

I filtered my set of users(array) with if(elem.id_verified). I now get 77 users objecta. I just want to take the number of these objects. I tried with console.log(this.numOfunverifiedUsers.length) but i get 77 underfined. My question is how to assemble all objects and get that number. Maybe my logic is going in the wrong direction.
this.users=response.data.users
this.numOfunverifiedUsers = []
this.users.forEach(elem => {
if (elem.id_verified === 0) {
this.numOfunverifiedUsers = elem
console.log(this.numOfunverifiedUsers.length)
}
})
this.numOfunverifiedUsers.push(elem)
Push the element in array.
this.numOfunverifiedUsers = elem , replace it with above
This should work too:
console.log(this.users.filter(function (val) {
return val.id_verified === 0
}).length)
filter items that are id_verified === 0 and count their length.
I think would be better you build that list with a filter:
this.numOfunverifiedUsers = this.users.filter(
user => user.id_verified === 0
);
console.log(this.numOfunverifiedUsers);
console.log(this.numOfunverifiedUsers.length);
If you want to read about filter: Filter method
With this.numOfunverifiedUsers = elem, you are assigning 'elem' to an array reference. As a result, you get exceptions which make the '=' operator return the undefined primitive type (as the result of function errors; see undefined - JavaScript | MDN). What you want to do is either add the element iteratively into the array the "old way", via element assigning, or just use the OOP way via the push method. The former wouldn't require a count function, as you can do something like that:
var count = 0; //outside the forEach
...
if (elem.id_verified === 0) {
{
this.numOfunverifiedUsers[count++]=elem
console.log(count)
}
...
However, as others pointed out, using a filter makes the code much more clean and readable
This would work better with the use of a Filter
console.log(this.users.filter(function (val) {
return val.id_verified === 0
}).length)
filter items that are id_verified === 0 and count their length.

replace object in array base on index

So, Im using react and I need to keep adding objects to an array of objects (object may have the same index, thats why I check for label and index). When the object that I want to add has the same label property as one that already is in that array, it should replace the previous object. So, lets say, only one object for each label. What I have works until I work with more then one label. When I do so, the array accepts more than one objects for each label...
if (this.state.thumbnailsAtivas.some(thumbnail => {
thumbnail.index === textura.index
}) && this.state.thumbnailsAtivas.some(thumbnail => {
thumbnail.label === textura.label
})) {
console.log("already in array");
}
else if (this.state.thumbnailsAtivas.some(thumbnail => thumbnail.label === textura.label)) {
console.log("label already with item");
this.state.thumbnailsAtivas.some((thumbnail, index) => {
const tempData = (this.state.thumbnailsAtivas).slice(0);
tempData[index] = textura;
this.setState({thumbnailsAtivas: tempData})
})
} else {
this.setState({thumbnailsAtivas: [...this.state.thumbnailsAtivas, textura]},);
}
You can use another Array function called findIndex which have the same usage as some but returns a result like indexOf does (returns the index of the element in an array or -1 if no element matches):
let index = this.state.thumbnailsAtivas.findIndex(
thumbnail => thumbnail.label === textura.label
);
if(index !== -1) {
this.state.thumbnailsAtivas[index] = yourNewObject;
}
Note: To optimise your code a little bit, you could get rid of the call to some and use findIndex (once) for both checking existence and finding the index.

JavaScript's 'forEach' misunderstanding

This function works properly:
function task02(arr) {
var out = [];
arr = arr.forEach(function(item, i){
(item > 0) ? out.push(1) : out.push(0);
});
return out;
}
And this one's not (outputs undefined):
function task02(arr) {
arr = arr.forEach(function(item, i){
(item > 0) ? item = 1 : item = 0;
});
return arr;
}
I've tried using both item and item[i], but it's not working. Can someone please explain to me, why this is not working?
Can someone please explain to me, why this is not working?
JavaScript is pass/call/assign by value. That implies that assigning a value to a variable won't magically change the value of another variable (or an array element).
Simpler example:
var foo = 42;
var bar = foo;
foo = 21;
bar will still have the value 42.
In your case, assigning to item won't change the array element.
As always, if you use an unfamiliar method, read its documentation first.
The callback function in your second example doesn't have any side-effects. It just iterates over the array, does the comparison and that's it. This is the main difference between .forEach (which iterates over the array, but returns undefined) and array methods such as .map, .filter, .reduce that iterate, execute the callback on every item and return a modified array.
If you want to avoid a temporary array you should use Array.map in this case:
function task02(arr) {
return arr.map(function(item, i){
return (item > 0) ? 1 : 0;
});
}

Categories

Resources