javascript for loop and put into a new array [duplicate] - javascript

This question already has answers here:
Modifying a copy of a JavaScript object is causing the original object to change
(13 answers)
Closed 5 years ago.
Here is the code i have:
let testp = {
value: ''
}
let data = [];
for (let i = 0; i < 5; i++) {
testp.value = i;
data.push(testp);
}
console.log(data)
The data return is:
[ { value: 4 },
{ value: 4 },
{ value: 4 },
{ value: 4 },
{ value: 4 } ]
why? I think the result is like this:
[ { value: 0 },
{ value: 1 },
{ value: 2 },
{ value: 3 },
{ value: 4 } ]

You're pushing a reference to the object testp into the array 5 times, editing the value of value each time.
Here's another example:
let foo = { 'a': 1 };
let bar = [foo, foo, foo];
foo.a = 2;
console.log(foo[2]);
// 2
The array bar contains three references to foo. Changing the content of the object will change the content of the object everywhere it is referenced.
If you want new objects you have to create them somewhere. For example:
// Function that constructs the new objects
let foo = (value) => { return { "value": value } };
let data = [];
for (let i = 0; i < 5; i++) {
data.push(foo(i));
}

Assigning testp.value inside the loop was causing the problem.Instead you could do
let testp = {
value: ''
}
let data = [];
for (let i = 0; i < 5; i++) {
data.push({
value: i
});
}
console.log(data)

Related

Writing a pre-computed object functions based on its existing functions [duplicate]

This question already has answers here:
Self-references in object literals / initializers
(30 answers)
Closed 1 year ago.
Is there a better way to write this? Ideally I want to write pre_calculated_h inside the object literal, somehow.
const obj = {
long_calc_f(x) {return 5*x}, //Some time consuming calculation
g(x) {return x + 2},
}
obj.pre_calculated_h = function(n) {
const pre_calculated_values = []
for (var i = 0; i < n; i++) pre_calculated_values.push(this.g(this.long_calc_f(i)))
return function(x) {return pre_calculated_values[x]}
}.call(obj, 20)
You can define a getter and reference object as this w/o passing it explicitly. Not sure if it is by any means better :) But the downside you will need to reference property name twice.
const obj = {
long_calc_f(x) {
return 5 * x
}, //Some time consuming calculation
g(x) {
return x + 2
},
get pre_calculated_h() {
console.log(`Precalculating`)
const pre_calculated_values = []
for (var i = 0; i < 20; i++) pre_calculated_values.push(this.g(this.long_calc_f(i)))
const value = function(x) {
return pre_calculated_values[x]
};
Object.defineProperty(this, 'pre_calculated_h', {
enumerable: true,
writable: false,
value
});
return value
}
}
console.log(obj.pre_calculated_h(1), obj.pre_calculated_h(3), obj.pre_calculated_h(15))

Very simple increment function in objects list

I’m trying to replicate a very simple function that I can get to work with arrays but not with objects. I just want to be able to run a function that logs the next object number as with the numbers array.
Take this working array as an example:
var numbers = [4,2,6],
count = 0;
incrementArr();
function incrementArr() {
if (count < numbers.length) { // if not last array element
console.log(numbers[count]);
count++;
} else {
console.log(numbers[0]);
count = 1;
}
}
Whenever you run the incrementArr function, it’ll just log the next number and then return to the start if the current state (count) is at the end.
However, I cannot replicate the same principle with this object list:
var objs = {
first: { // doesn't have to have 'first'
"number": 4
},
second: { // doesn't have to have 'second'
"number": 2
},
third: { // doesn't have to have 'third'
"number": 6
}
},
count = 0;
incrementObj();
function incrementObj() {
if (count < Object.keys(objs).length) { // if not last obj element
//objs["first"].number
console.log(objs[count].number);
count++;
} else {
console.log(objs["first"].number); // what if no "first" in objects?
count++;
}
}
How could the incrementObj function work the same way that the previous incrementArr function works?
It seems that I can’t pick the specific object instance (e.g. numbers[1] from the array would pick the 2nd number, but only objs[“second”].number would pick the 2nd object, which isn’t iterable if you know what I mean). How could I get a workaround for typical circumstances like this?
So essentially, what’s the difference between this:
first: { // doesn't have to have 'first'
"number": 4
}
and:
{ // doesn't have to have 'first'
"number": 4
}
Why have the "first" etc? (called the key?)
Is there generally a better way of going about object lists (it's difficult to explain)? Thanks for any advice here.
You could take a closure over the object and get the keys and store an index. The returned function get the value and increment and adjusts the index.
function increment(object) {
var keys = Object.keys(object),
index = 0;
return function() {
var value = object[keys[index]].number;
index++;
index %= keys.length;
return value;
};
}
var objs = { first: { number: 4 }, second: { number: 2 }, third: { number: 6 } },
incrementObj = increment(objs);
console.log(incrementObj());
console.log(incrementObj());
console.log(incrementObj());
console.log(incrementObj());
Try this, it access keys through the array generated from keys, objects are unordered list that means you will have to at least order the keys and access them in the array order.
const keysArr = Object.keys(objs);
function incrementObj() {
if (count < keysArr.length) { // if not last obj element
//
console.log(objs[keysArr[count]].number);
count++;
} else {
console.log(objs["first"].number); // what if no "first" in objects?
count++;
}
}
I propose using iterators
See this codepen
If your object have specific shapes, then you use this as a lens to find the number property you want. I'm not sure how you want to use the iterator and have return both the key and the value as separate properties, but you can as well return { [keys[nextIndex]]: values[nextIndex] } or find other shape (the world is your oyster).
Provided you go this length, why not try use RxJs to make your object an observable?
var objs = {
first: { // doesn't have to have 'first'
"number": 4
},
second: { // doesn't have to have 'second'
"number": 2
},
third: { // doesn't have to have 'third'
"number": 6
}
}
function propertyIterator(obj) {
const keys = Object.keys(obj)
const values = Object.values(obj)
const length = keys.length
let nextIndex = 0
return {
next: function() {
const value = {
key: keys[nextIndex],
value: values[nextIndex]
}
let done = false
if (nextIndex >= length) {
done = true
}
nextIndex += 1
return { current: value, done: done}
}
}
}
const incrementObj = propertyIterator(objs)
let result = incrementObj.next()
console.log(result.current.key, result.current.value.number || NaN)
result = incrementObj.next()
console.log(result.current.key, result.current.value.number || NaN)
result = incrementObj.next()
console.log(result.current.key, result.current.value.number || NaN)
using generators, see this codepen:
const objs = {
first: { // doesn't have to have 'first'
"number": 4
},
second: { // doesn't have to have 'second'
"number": 2
},
third: { // doesn't have to have 'third'
"number": 6
}
}
const inc = defaultValue => prop => function* (obj) {
for(let key in obj) {
yield obj[key][prop] || defaultValue
}
}
const getNumber = inc(NaN)('number')
const it = getNumber(objs)
let result = it.next()
while (!result.done) {
console.log(result.value)
result = it.next()
}

Need help correcting & combining two functions into one

The Question is
Create a function called divisibles() that will take each object in upper and find all
objects in lower that evenly divide into it, ignoring zero. The function should return an
object that is upper but each object has an additional key called found and the value
for that key is an array containing each item from lower that was evenly divided into it.
Output the result of the function to the console.
Here's my code so far, I know I'm doing something very wrong and can't figure it out. I have it in two functions, can't figure out how to make it one, and my output doesn't look correct either.
function divisibles(number, myArrayLower) {
let divisibleArray = [];
let count = 0;
for (let i = 0; i < myArrayLower.length; i++) {
if (number % myArrayLower[i].value === 0) {
divisibleArray[count++] = {name: myArrayLower[i].name, value: myArrayLower[i].value};
}
}
return divisibleArray;
}
function findDivisibles(myArrayUpper, myArrayLower) {
let divisiblesArray = [];
for (let i = 0; i < myArrayUpper.length; i++) {
let divisibleArray = divisibles(myArrayUpper[i].value, myArrayLower);
divisiblesArray[i] = {
name: myArrayUpper[i].name, value: myArrayUpper[i].value,
found: divisibleArray
};
}
return divisiblesArray;
}
Here's the call function
let resultArray = findDivisibles(myArrayUpper, myArrayLower);
Here is my console.log
let resultArray = findDivisibles(myArrayUpper, myArrayLower);
for (let i = 0; i < resultArray.length; i++) {
console.log("Name: " + resultArray[i].name + " Value: " + resultArray[i].value + " Found: ");
let tmpArray = resultArray[i].found;
for (let k = 0; k < tmpArray.length; k++) {
console.log(" Name: " + tmpArray[k].name + " Value: " + tmpArray[k].value);
}
}
The desired output will look something like this
{
name: ”Nathan15”,
value: 15,
found:[
{ name: “nathan3”, value: 3},
{ name: “nathan15”, value: 15} ]
}
This is my output
My output looks like this
Name: Nathan586 Value: 2930 Found:
Name: Nathan587 Value: 2935 Found:
Name: Nathan588 Value: 2940 Found:
Name: nathan1 Value: 3
Name: nathan2 Value: 6
Name: nathan4 Value: 12
I can add the rest of the question, code I wrote for previous parts of this question if it helps

Find the index value of an array based on an array item object property value [duplicate]

This question already has answers here:
Getting index of an array's element based on its properties
(7 answers)
Closed 5 years ago.
I have this array here (stressValues):
[ { angeredoutsidecontrol: 1 }, { difficultiespileup: 2 } ]
I'd like to find the array index value based on the property name of one of the contained objects, such as angeredoutsidecontrol, which would return 0
How can I achieve this?
This is what I have so far:
for(const value of values) {
const stressValue = Object.values(value)[0];
const valueName = Object.keys(value)[0];
for (const name in stressValues) {
if (name === valueName) {
console.log(name);
console.log(values.indexOf(name)); // trying to get it to return 0
}
}
}
const arr = [ { angeredoutsidecontrol: 1 }, { difficultiespileup: 2 } ];
function checkForKey(arr, key) {
// loop through array
for(let i = 0; i < arr.length; ++i) {
const value = arr[i];
// if value has the key, return the index
if (value.hasOwnProperty(key)) {
return i;
}
}
}
console.log('angeredoutsidecontrol', checkForKey(arr, 'angeredoutsidecontrol'));
console.log('difficultiespileup', checkForKey(arr, 'difficultiespileup'));
If the objects have always only one property, you can use Object.keys with findIndex:
var stressValues = [ { angeredoutsidecontrol: 1 }, { difficultiespileup: 2 } ];
var angerIndex = stressValues.findIndex((value) => Object.keys(value)[0] === 'angeredoutsidecontrol');
console.log(angerIndex);
EDIT: If you want a more generic solution, you can use includes, so we check if the object includes, in its keys, the specified one:
var stressValues = [ { angeredoutsidecontrol: 1, sadness: 3 }, { difficultiespileup: 2 } ];
var angerIndex = stressValues.findIndex((value) => Object.keys(value).includes('angeredoutsidecontrol'));
console.log(angerIndex);

indexOf returns -1 for value that exists in array [duplicate]

This question already has answers here:
indexOf method in an object array?
(29 answers)
Closed 8 years ago.
I have an array defined like so:
var numeric = [{ Value: "0" }, { Value: "1" }, { Value: "2" }, { Value: "3" }];
I'm trying to determine if a particular value exists in this array. I've tried all of the following lines which all return -1.
numeric.indexOf(1);
numeric.indexOf("1");
numeric.indexOf({Value: "1"});
Assume I have no control over how the array is defined. How can I determine if a value exists in this particular kind of array?
You would have to iterate through the array and check for the property.
var numeric = [{ Value: "0" }, { Value: "1" }, { Value: "2" }, { Value: "3" }];
var index=-1;
for(var i = 0; i<numeric.length; i++)
if(numeric[i].Value === "2") {
index = i;
break;
}
console.log(index);
You can loop throught object with a loop:
var numeric = [{
Value: "0"
}, {
Value: "1"
}, {
Value: "2"
}, {
Value: "3"
}];
for (var key in numeric) {
var value = numeric[key];
if (value.Value == "1") {
console.log("ok");
}
}
After #MattBurland comment you can use regular for too:
var numeric = [{
Value: "0"
}, {
Value: "1"
}, {
Value: "2"
}, {
Value: "3"
}];
for (var i = 0; i < numeric.length; i++) {
var value = numeric[i];
if (value.Value == "1") {
console.log("ok");
}
}
Since numeric is an array you can use .findIndex():
var search = 1;
var found = numeric.findIndex(function(n) {return n.value == search});
found will be index of item with value == 1, if thats not found it will be -1.
Reference here.
If you need a boolean result it's better to use .some():
var found = numeric.some(function(n) {return n.value == search;});
Reference here. Note that both functions are not supported by older browsers.

Categories