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.
Related
For the function Objectgenerator(input1, input2), take arrays as input. Each array must have only two elements. The goal is to use JavaScript to create an object that will have the first elements of each array as the key and the second element as the value. In the event more than one array has similar first elements, then consider only the value of the last one. For example:
Examples:
Objectgenerator(["key1","value1"], ["key2","value2"],["key1","value3"]) would result in the following output --> {key1:"value3", key2:"value2"}
Objectgenerator(["Key1","value1"],["key2","value2"]) --> {key1:"value1",key2:"value2"}
Errors would result if the following parameters are passed:
Objectgenerator([])
Objectgenerator()
Objectgenerator('testing')
Objectgenerator(22)
Objectgenerator(['key1','valuea','valueb'],['key2','valuec'])
Basically, Array#reduce is your best bet. Setting it up is straight forward. The actual work is in verifying that the input is valid.
function objectGenerator(...arr) {
if( arr.length &&
arr.every(el => Array.isArray(el) && el.length === 2) ) {
return arr.reduce((obj, [key,value]) => ({...obj,[key]:value}),{});
} else {
const err = new Error('Input is not valid');
throw err;
}
}
console.log( objectGenerator(["key1","value1"], ["key2","value2"],["key1","value3"]) );
console.log( objectGenerator(["Key1","value1"],["key2","value2"]) );
i have below object structure like as in below image and i am trying to match with the inner object property(like massing type id) with the existing ID and if it is match i need to get the name of that object and push it to array and set that array in state object,
and the code is looks like as below
Object.values(constructionSets).forEach(item => {
console.log(item);
const constructionSetItem = [];
if (
item.ashraeClimateZone?.id === ashraeClimateZoneId &&
item.massingType?.id === massingTypeId &&
item.sourceOfData?.id === energyCodeId
) {
setConstruction(constructionSetItem.push(item.name));
}
});
and when i log item i am getting array of objects instead of single object, could any one please let me know where i am doing wrong with the above code?
thanks in advance.
From what I see in the information you gave, that constructionSets variable is already an Array so to loop it, you just need to do:
constructionSets.forEach(item => {...})
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
I'm recursively sorting a deeply nested array of objects by a deeply nested obj that is keyed by id.
This function works but when I console.log while invoking the function the result is undefined.
The unsorted array of objects passed as an argument does get sorted if I console.log it before and after the call to this function, but that is not being returned from the function call - it is a mutation, which I'm looking to avoid.
A couple of things I've tried:
Instead of the initial call to .map(), using .reduce(), and
adding an empty array as the accumulator, which allows the function
to return but it does not sort :/
Returning the array I'm calling .map() on at the very end works -
but this seems like a hack, and it also encloses the result in an
array.
I've tried carefully placing returns in different places - but what usually results is [undefined], or arrays of arrays that
contain undefined
function sortDeepNestedArray(unsortedArray, sortedObj){unsortedArray.map((obj) => {
const children = obj.Children;
const Id = obj.Id
if (children && children.every(o => !o.Children)) {
Object.keys(sortedObj).map(key => {
if (Id === key) {
return children.sort((a, b) => {
a = sortedObj[key].Children[a.Id]
b = sortedObj[key].Children[b.Id]
return a - b
});
}
});
}
Object.keys(sortedObj).map(key => {
const isNotBaseCase = children &&
children.every(o => o.Children) &&
Id === key &&
sortedObj[key] &&
sortedObj[key].Children
if (isNotBaseCase) {
sortDeepNestedArray(children, sortedObj[key].Children);
}
});
});
}
If I was to map through an array of objects of data and only wanted to render a single element from the array based on a certain condition like below:
dataArray.map((element, i) => {
if(i === currentElement){
return (
<div>{element.data}</div>
)
} else {
return null;
}
});
Would that be acceptable? this seems to return what I am after but was curious if this was the most efficient way to go about it because this still returns an array with a length of the data array with all null elements except on the desired single element.
Using map on an array will return another array with your function performed on each element, so the function you are using is literally pushing the value 'null' into the return array for any element that doesn't pass your condition. You could just use
dataArray.map((ele, i) => {
if(i === currentElement){
return (
<div>{element.data}</div>
)
}
and the map will simply do nothing with any element that does not pass the condition.
Mapping over an array in React is usually (often?) used for creating <li> tags, and React might get cranky in your console about not having a key. If you see that, check out this link here: https://reactjs.org/docs/lists-and-keys.html
You could use the find function to get the value you want to render rather than rendering a bunch of null values.
const element = dataArray.find((el, i) => i === currentElement);
if(element) {
return (<div>{element.data}</div>);
}