Replacing array elements in Javascript produces unexpected results - javascript

I'm trying to replace array elements (generic objects) with their alternatives (specific Objects), but objects within the original array remain unchanged.
class SpecificObject{
}
this.Objects = [{},{}];
this.Objects.map((signer,index) => {
//convert json generics to js objects
this.Objects[index] = new SpecificObject(signer);
});
console.log(this.Objects);
Not sure if the code snippet illustrates the problem correctly, but what i expect to see is:
[
SpecificObject{},
SpecificObject{}
]
I even tried cloning the original object to do the iteration but it didn't help. Must be missing something stupid. Is there a way to achieve what i need with lodash?
Edit(followed the answer advise):
Now i do the following:
console.log('signers-before', this.Signers);
this.Signers.map(signer => new SigningTableSigner(signer));
console.log('signers-after',this.Signers);
And this is what i get in my log(object still remain generic):
Edit2
Oops, i forgot the assignment. this.Signers =
now like this everything works as expected:
console.log('signers-before', this.Signers);
this.Signers = this.Signers.map(signer => new SigningTableSigner(signer));
console.log('signers-after',this.Signers);

There is no need to modify the collection while you are iterating it. Just return the object from the map.
this.Objects = this.Objects.map((signer,index) => new SpecificObject(signer));

Map is used when you wants to return an array. You can just use forEach for what you are trying to do. But I think this will look better
this.Objects = this.Objects.map(signer => new SpecificObject(signer))

You don't use map correctly. You should be just returning objects inside arrow functions. map actually returns new array, which contains elements which were created by applying function you have provided. Because of that you also have to reassign result ot this.Objects.
this.Objects = this.Objects.map(signer => {
//convert json generics to js objects
return new SpecificObject(signer);
})

Related

I'm trying to use reduce high order function in my javascript code but keeps giving me #<Object> not a function

I'm doing an assignment using javascript language for educational purposes, but i'm a beginner. I'm having some problems trying to use reduce function.
What i'm trying to do is to use reduce to filter the following.
"Receive a string array in propNames and an object array in objs. Return a new object array with objects produced by applying the filterProperties function with propNames to each object in objs."
I already code filterProperties and its working fine to match propNames with only one object. I leave the code down below:
function filterProperties(propNames, obj) {
let output = {}
let objKeys = Object.keys(obj);
const matchingElems = propNames.sort().filter(elem => objKeys.includes(elem))
matchingElems.forEach(elem => output[elem] = obj[elem])
return output
}
So just to sum up, i would like to use reduce to iterate and output an array with the properties matching propNames and objs.
My code is not working, i'm a complete beginner and I didn't understand well how to use reduce function. I leave my code below, so that anyone can help me solving this issue.
function filterPropertiesN(propNames,objs) {
objs.reduce(filterProperties(propNames, objs))
}
many thanks in advance!

Why push does not working with set methond in Map object

So very quick question here which I wasn't able to get sorted when searching google.
I have some code that works which has a Map object this.tweet and a (key,value) of (string,array). I push a value into the array and re-set Map object.
const newTweet = this.tweet.get(tweetName) || [];
newTweet.push(time);
this.tweet.set(tweetName, newTweet);
However, I am a minimalist freak and want a one-liner. When I want to add something to the array, I was wondering why I am not able to do this
this.tweet.set(tweetName, newTweet.push(time));
I keep getting a newTweet.push(time) is not a function error.
Thanks
Look at some documentation for push
The push() method adds one or more elements to the end of an array and returns the new length of the array.
Since you want to pass the array to set you can't use the return value of push.
You could create a completely new array instead:
const newTweet = this.tweet.get(tweetName) || [];
this.tweet.set(tweetName, [...newTweet, time]);

javascript push associative array in another

I have two associative arrays and want to push one completely to the other.
my current code:
LT_WORK_PACKAGE.data[i].STOCK_DOCCAT = stock_data.STOCK_DOCCAT;
LT_WORK_PACKAGE.data[i].STOCK_DOCNO = stock_data.STOCK_DOCNO;
LT_WORK_PACKAGE.data[i].STOCK_ITMNO = stock_data.STOCK_ITMNO;
im looking for something like this:
LT_WORK_PACKAGE.data[i].push(stock_data);
.push is for adding items to an array. You do have an object , and to copy multiple properties into an object,you can use Object.assign:
Object.assign(
/*to:*/ LT_WORK_PACKAGE.data[i],
/*from:*/ stock_data
);
You can use LT_WORK_PACKAGE.data[i] = stock_data.
Note that the previous content (if it exists) of LT_WORK_PACKAGE.data[i] will be replaced by a reference to stock_data. Any changes made in stock_data will be done in LT_WORK_PACKAGE.data[i] If you want a copy, you can use : LT_WORK_PACKAGE.data[i] = JSON.parse(JSON.serialize(stock_data))

Copying an array of objects into another array in javascript (Deep Copy)

Copying an array of objects into another array in javascript using slice(0) and concat() doesnt work.
I have tried the following to test if i get the expected behaviour of deep copy using this. But the original array is also getting modified after i make changes in the copied array.
var tags = [];
for(var i=0; i<3; i++) {
tags.push({
sortOrder: i,
type: 'miss'
})
}
for(var tag in tags) {
if(tags[tag].sortOrder == 1) {
tags[tag].type = 'done'
}
}
console.dir(tags)
var copy = tags.slice(0)
console.dir(copy)
copy[0].type = 'test'
console.dir(tags)
var another = tags.concat()
another[0].type = 'miss'
console.dir(tags)
How can i do a deep copy of a array into another, so that the original array is not modified if i make a change in copy array.
Try
var copy = JSON.parse(JSON.stringify(tags));
Try the following
// Deep copy
var newArray = jQuery.extend(true, [], oldArray);
For more details check this question out What is the most efficient way to deep clone an object in JavaScript?
As mentioned Here .slice(0) will be effective in cloning the array with primitive type elements. However in your example tags array contains anonymous objects. Hence any changes to these objects in cloned array are reflected in tags array.
#dangh's reply above derefences these element objects and create new ones.
Here is another thread addressing similar situation
A nice way to clone an array of objects with ES6 is to use spread syntax:
const clonedArray = [...oldArray];
MDN
Easiest and the optimistic way of doing this in one single line is using Underscore/Lodash
let a = _.map(b, _.clone)
You just need to use the '...' notation.
// THE FOLLOWING LINE COPIES all elements of 'tags' INTO 'copy'
var copy = [...tags]
When you have an array say x, [...x] creates a new array with all the values of x. Be careful because this notation works slightly differently on objects. It splits the objects into all of its key, value pairs. So if you want to pass all the key value pairs of an object into a function you just need to pass function({...obj})
Same issue happen to me. I have data from service and save to another variable. When ever I update my array the copied array also updated. old code is like below
//$scope.MyData get from service
$scope.MyDataOriginal = $scope.MyData;
So when ever I change $scope.MyData also change $scope.MyDataOriginal.
I found a solution that angular.copy right code as below
$scope.MyDataOriginal = angular.copy($scope.MyData);
I know that this is a bit older post but I had the good fortune to have found a decent way to deep copy arrays, even those containing arrays, and objects, and even objects containing arrays are copied... I only can see one issue with this code is if you don't have enough memory I can see this choking on very large arrays of arrays and objects... But for the most part it should work. The reason that I am posting this here is that it accomplishes the OP request to copy array of objects by value and not by reference... so now with the code (the checks are from SO, the main copy function I wrote myself, not that some one else probably hasn't written before, I am just not aware of them)::
var isArray = function(a){return (!!a) && (a.constructor===Array);}
var isObject = function(a){return (!!a) && (a.constructor===Object);}
Array.prototype.copy = function(){
var newvals=[],
self=this;
for(var i = 0;i < self.length;i++){
var e=self[i];
if(isObject(e)){
var tmp={},
oKeys=Object.keys(e);
for(var x = 0;x < oKeys.length;x++){
var oks=oKeys[x];
if(isArray(e[oks])){
tmp[oks]=e[oks].copy();
} else {
tmp[oks]=e[oks];
}
}
newvals.push(tmp);
} else {
if(isArray(e)){
newvals.push(e.copy());
} else {
newvals.push(e);
}
}
}
return newvals;
}
This function (Array.prototype.copy) uses recursion to recall it self when an object or array is called returning the values as needed. The process is decently speedy, and does exactly what you would want it to do, it does a deep copy of an array, by value... Tested in chrome, and IE11 and it works in these two browsers.
The way to deeply copy an array in JavaScript with JSON.parse:
let orginalArray=
[
{firstName:"Choton", lastName:"Mohammad", age:26},
{firstName:"Mohammad", lastName:"Ishaque", age:26}
];
let copyArray = JSON.parse(JSON.stringify(orginalArray));
copyArray[0].age=27;
console.log("copyArray",copyArray);
console.log("orginalArray",orginalArray);
For this i use the new ECMAScript 6 Object.assign method :
let oldObject = [1,3,5,"test"];
let newObject = Object.assign({}, oldObject)
the first argument of this method is the array to be updated,
we pass an empty object because we want to have a completely new object,
also you can add other objects to be copied too :
let newObject = Object.assign({}, oldObject, o2, o3, ...)

Creating multi-dimensional arrays in javascript, error in custom function

I was trying to define an array (including other arrays as values) in a single javascript statement, that I can loop through to validate a form on submission.
The function I wrote to (try to) create inline arrays follows:
function arr(){
var inc;
var tempa = new Array(Math.round(arguments.length/2));
for(inc=0; inc<arguments.length; inc=inc+2) {
tempa[arguments[inc]]=arguments[inc+1];
}
return tempa;
}
This is called three times here to assign an array:
window.validArr = arr(
'f-county',arr('maxlen',10, 'minlen',1),
'f-postcode',arr('maxlen',8, 'minlen',6)
);
However in the javascript debugger the variable is empty, and the arr() function is not returning anything. Does anyone know why my expectations on what this code should do are incorrect?
(I have worked out how to create the array without this function, but I'm curious why this code doesn't work (I thought I understood javascript better than this).)
Well from what your code does, you're not really making arrays. In JavaScript, the thing that makes arrays special is the management of the numerically indexed properties. Otherwise they're just objects, so they can have other properties too, but if you're not using arrays as arrays you might as well just use objects:
function arr(){
var inc;
var tempa = {};
for(inc=0; inc<arguments.length; inc=inc+2) {
tempa[arguments[inc]]=arguments[inc+1];
}
return tempa;
}
What you're seeing from the debugger is the result of it attempting to show you your array as a real array should be shown: that is, its numerically indexed properties. If you call your "arr()" function as is and then look at (from your example) the "f-county" property of the result, you'll see something there.
Also, if you do find yourself wanting a real array, there's absolutely no point in initializing them to a particular size. Just create a new array with []:
var tempa = [];
Your code works. Just inspect your variable, and you will see that the array has the custom keys on it. If not expanded, your debugger shows you just the (numerical) indixed values in short syntax - none for you.
But, you may need to understand the difference between Arrays and Objects. An Object is just key-value-pairs (you could call it a "map"), and its prototype. An Array is a special type of object. It has special prototype methods, a length functionality and a different approach: to store index-value-pairs (even though indexes are still keys). So, you shouldn't use an Array as an associative array.
Therefore, their literal syntax differs:
var array = ["indexed with key 0", "indexed with key 1", ...];
var object = {"custom":"keyed as 'custom'", "another":"string", ...};
// but you still can add keys to array objects:
array.custom = "keyed as 'custom'";

Categories