I have a simple array of objects and I'd like to check if all the object in that array has the same value for a specific property.
const arr = [{
name: "Test",
value: 90
}, {
name: "OP",
value: 90
}, {
name: "Test",
value: 120
}]
Here I want to compare all the value property of every object element.
// get first objects value for comparison
let same_value = arr[0]['value'];
for(let i = 0; i < arr.length; i ++) {
if (arr[i]['value'] != same_value) {
return false;
}
}
Related
I have an array of objects, and each object has a nested object with a key that I would like to increment each iteration with a higher multiplier.
I have an object:
object = {
id: 1,
innerArr: [
{
key: 50
},
{
key: 20
}
]
}
then I want to:
Push it to a new array, X times.
multiply the 'key' with growing increments in each iteration
const arr = [];
let increment = 0.85;
for (let i = 0; i < 7; i++) {
const { id } = object;
object.innerArr.forEach(obj => {
obj.key *= increment;
})
arr.push({
id,
innerArr
})
increment += 0.05; // (1:) 0.9, (2:) 0.95...
}
The resulting array should look something like this:
arr = [
{
id: 1,
innerArr: [
{
key: 42.5
},
{
key: 17
}
]
},
{
id: 1,
innerArr: [
{
key: 45
},
{
key: 18
}
]
},
{
id: 1,
innerArr: [
{
key: 47.5
},
{
key: 19
}
]
} // and the rest...
]
But, for some (probably obvious) reason, when I do something similar, all the keys get the last increment only (the 7th iteration of increment += 0.05).
How can I get the desired output? and, what mechanism am I missing that cause this behavior.
Thanks for the help!
Found the answer! when I copied the innerArr, I did not actually copy its objects but referenced them, so the final arr contains only references to the initial object. So incrementing obj.key affects the initial innerArr object.
The solution is to:
deep copy the innerArr
make changes on the copy
push the copy to arr
start over
const arr = [];
let increment = 0.85;
for (let i = 0; i < 7; i++) {
const { id } = object;
let newInnerArr = JSON.parse(JSON.stringify(innerArr));
object.newInnerArr.forEach(obj => {
obj.key *= increment;
})
arr.push({
id,
newInnerArr
})
increment += 0.05; // (1:) 0.9, (2:) 0.95...
}
Hope it helps someone :)
I have a function inside of a react class component which generates properties. Since I want to be able to have duplicate properties, I've done it in a way that it is possible. However, I want those duplicate properties to be combined as a single value so that it can be displayed in the render function as a single property with a bigger value instead of 2 properties with smaller values. How can I achieve this based on the below code?
changePropertyState = () => {
let rngProperties = []
let maxProp = this.state.rarity.maxProperties;
let minProp = this.state.rarity.minProperties;
let rngCurrentPropAmount = Math.floor(Math.random() * (maxProp - minProp + 1) + minProp);
// the actual properties for an item based on the array of properties
for (let i = 0; i < rngCurrentPropAmount; i++) {
let rngNum = Math.floor(Math.random() * (itemProperties.length))
rngProperties.push(itemProperties[rngNum])
}
let proxyProperties = []
// setting the values for each property based on the min and max of that property
for (let j = 0; j < rngProperties.length; j++) {
let rngValue = this.getRandomNumber(rngProperties[j].min, rngProperties[j].max);
rngProperties[j].value = rngValue;
// creating a proxy to store unique values for each property,
let obj = {
id: rngProperties[j].id,
name: rngProperties[j].name,
min: rngProperties[j].min,
max: rngProperties[j].max,
value: rngProperties[j].value
}
proxyProperties.push(obj);
}
//setState() has an inbuilt functionality for a callback function, in which we can console.log the newly changed state
this.setState({
properties: proxyProperties
}, () => {
// console.log('propF', this.state)
});
}
An expected output of the above code is the below picture.
What I want to do is combine the 2 properties called (in this case) "Area Damage" so that only 1 property is listed but the value is 25 (again, in this case).
The itemProperties is an array of objects that have the following structure:
id: 1,
name: "intelligence",
min: 1,
max: 10,
value: 0
The rngCurrentPropAmount can be replaced with any integer for testing purposes. This is the amount of properties to be added.
The logic is to first group the array by name then merge them using reduce & summing the value. Bit tricky but working. Hope this is what was needed. The initial array has 4 elements & the final one has two. value is summed up.
const arr = [
{
id: 1, name: "intelligence", min: 1, max: 10, value: 11
},
{
id: 1, name: "intelligence", min: 1, max: 10, value: 4
},
{
id: 2, name: "dexterity", min: 1, max: 10, value: 3
},
{
id: 2, name: "dexterity", min: 1, max: 10, value: 8
}
];
//group an array by property
function groupBy(arr, property) {
return arr.reduce(function(memo, x) {
if (!memo[x[property]]) {
memo[x[property]] = [];
}
memo[x[property]].push(x);
return memo;
}, {});
}
//group by name
const grouped = groupBy(arr, "name");
const keys = Object.keys(grouped);
var output = [];
//loop keys
keys.forEach(key => {
//merge using reduce
const out = grouped[key].reduce((acc, current) => {
return {
id: current.id,
name: current.name,
min: current.min,
max: current.max,
value: acc.value + current.value
}
});
output.push(out);
});
console.log(output);
So I currently have a bunch of objects inside an array like below. However, I'm now trying to write a function that allows me to add another key|value into the object that was added last.
My current idea is using the arrayname.length - 1 to work out the position of the object within the array.
Would I need to create a temporary array to store the new object and then set (tempArray = oldArray) at the end of the function or would I concatinate them both?
const state = [
{
userId: 1,
},
{
Name: name,
},
{
age: 52,
},
{
title: "et porro tempora",
}]
this is the current code
let objects = [];
const addParent = (ev) =>{
ev.preventDefault();
// getting the length of the objects array
let arrayLength = objects.length;
// if the length of the array is zero - empty or one then set it to default zero
// else if there is objects stored in the array minus 1 to get the array position
if(arrayLength <= 0){
arrayLength = 0;
}else{
arrayLength = objects.length - 1;
}
//make a temporary array to be able to push new parent into an existing object
var tempObjects = []
for (var index=0; index<objects.length; index++){
}
//create a new parent object key : value
let parent = {
key: document.getElementById('key').value,
value: document.getElementById('value').value
}
//push parent object key and value into object
//objects.push(parent);
}
document.addEventListener('DOMContentLoaded', () => {
document.getElementById('btn1').addEventListener('click', addParent);
});
There are multiple ways to do this.
Try this one
var objects = [{
name: "1"
}];
const addParent = (ev) => {
let parent = {
key: "some value",
value: "some value"
}
objects = Array.isArray(objects) ? objects : [];
let lastObjectIndex = objects.length - 1;
lastObjectIndex = lastObjectIndex > -1 ? lastObjectIndex : 0
objects[lastObjectIndex] = { ...objects[lastObjectIndex],
...parent
}
}
I think You want to add new value to last object of the array
Method 1
const state = [
{
userId: 1,
},
{
Name: name,
},
{
age: 52,
},
{
title: "et porro tempora",
}]
state[state.length - 1].newKey = "value"
console.log(state)
Method 2
const state = [
{
userId: 1,
},
{
Name: name,
},
{
age: 52,
},
{
title: "et porro tempora",
}]
// 1st method
state[state.length - 1] = {
...state[state.length - 1] ,
newKey : "value"
}
console.log(state)
You can probably use something like this:
const a = [
{ "a" : "a" },
{ "b" : "b" }
]
const c = a.map((obj, index) => {
if (index === a.length -1) {
return { ...obj, newProp: "newProp" }
}
return obj;
});
console.log(c)
This will add property on the last object using spread operator, you can look it up if you are new to JS but basically it will retain all the existing property and add the newProp to the object
Im facing a small issue in Javascript.
I have below Arrays.
var labels = ["labelOne", "labelTwo"];
var values1 = ["89", "9"];
var values2 = ["32", "78"];
Here we can place n number of values arrays like value3,value4....
Now how can i form an array of Objects by combining labels Array and their values are in values arrays. Im expecting the below output after combining above 3 arrays..
var mainArray = [{
label:"labelOne",
value:"89"
},
{
label:"labelTwo",
value:"9"
},
{
label:"labelOne",
value:"32"
},
{
label:"labelTwo",
value:"78"
}]
Can someone please help me to achieve the above output.
Thank you in advance
All that you need is a variable to know how many arrays should be added and access them in a loop using the advantage that Javascript lets you get them like this: window['variableName'] when they are defined in global scope.
var labels = ["labelOne", "labelTwo"];
var values1 = ["89", "9"];
var values2 = ["32", "78"];
var mainArray = [];
// Define a variable to know how many arrays should be added
var maxValues = 2;
function addValues(values) {
// Create new elements and push them into mainArray
mainArray.push({label:labels[0], value:values[0]});
mainArray.push({label:labels[1], value:values[1]});
}
// Do a loop from 1 to maxValues
for(let i = 1; i <= maxValues; i++) {
// Call the function with dynamic variable name
addValues(window['values' + i]);
}
console.log(mainArray);
If the order of your array isn't critical (and then, you might sort it later if it is), you can do like this:
const output = labels.map((label, index) => {
return [{ label, value: values1[index] }, { label, value: values2[index] }];
}).flat();
The map step, will give you an array like this:
[
[{ label: 'labelOne', value: 89 }, { label: 'labelOne', value: 32 }],
[{ label: 'labelTwo', value: 9}, { label: 'labelTwo', value: 78}]
]
By then calling flat, it'll transform it into:
[{ label: 'labelOne', value: 89 }, { label: 'labelOne', value: 32 }, { label: 'labelTwo', value: 9}, { label: 'labelTwo', value: 78}]
Which is what you wanted, from here you can sort the array if that matters for your use case.
I want to merge objects based on a property, and I want to use this property as the key for the merged array.
here is my code:
let mergedProfiles = [];
for (let set of profiles) {
if (Object.keys(mergedProfiles).indexOf(String(set.profile_id)) >= 0) { // if profile id exists
mergedProfiles[set.profile_id].push(set);
} else {
mergedProfiles[set.profile_id] = [];
mergedProfiles[set.profile_id].push(set);
}
}
example of profile object: {user_id: 17, name: "test", country: "US", bid: 0.02, profile_id: "1", user_id: 12}
the merge is working fine but for some reason I cant understand I always end up with empty as my first property in the mergedProfiles, any idea what am Imissing?
You could take an object instead of an array, because you get a sparse array with not used indices.
var profiles = [{ user_id: 17, name: "test", country: "US", bid: 0.02, profile_id: "1", user_id: 12 }],
mergedProfiles = {},
s;
for (s of profiles) {
if (!mergedProfiles[s.profile_id]) {
mergedProfiles[s.profile_id] = [];
}
mergedProfiles[s.profile_id].push(s);
}
console.log(mergedProfiles);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You will want to store the results in an object so you can reference by key.
const allProfiles = {};
for(let set of profiles) {
if(typeof allProfiles[set.profile_id] === "undefined") {
allProfiles[set.profile_id] = [set];
}
else {
allProfiles[set.profile_id].push(set);
}
}
The reason your first element is empty is that you are declaring an empty JavaScript array and then failing to initialize all of the elements.
If you do something like
var someArray = [];
someArray[5] = 10;
console.log(someArray); // [empty × 5, 5]
then the result is a sparse array where the first 5 elements (0 - 4) are all empty or in other words undefined. In your example you are doing the same as above where your profile_id is some integer greater than 0.