Javascript add elements to an object from another object - javascript

I have one object. The first element inside the data object looks like this:
data[0] = {name:"Bob", model:"Tesla", color:"white"};
and a second object, whose first element looks like this:
new_data[0] = {salary:"50000", age:"34"};
data and new_data are the same length, and each element inside of the new_data object needs to be appended onto the correlating data object, to make something like this:
data[0] = {name:"Bob", model:"Tesla", color:"white", salary:"50000", age:"34"};
I've used concat before to add elements into a single line object ( var
people = ["Dan","Bob"];
people.concat("Mike");
, but that same idea doesn't work here:
for ( var i = 0;i<data.length; i++ ) {
data[i] = data[i].concat(new_data[i]);
}
How do I go about looping through this?

As such you have tagged your question with jQuery, I've used its $.extend() method below (jQuery Documentation).
This is just a one liner solution for your case. By passing true to this method, you can easily merge object2 into object1, recursively. jQuery is smart to figure out that both of your objects are array of same length, so the output is an array and each item in the resulting array is a merged result from both objects.
Object.assign is quite new (ES6) and may not be supported in all browsers (Source). But this jQuery way can be a useful time saver for supporting all the browsers.
var collection1 = [{
name: "Bob",
model: "Tesla",
color: "white"
},
{
name: "Bob 1",
model: "Tesla 1",
color: "white 1"
}
];
var collection2 = [{
salary: "50000",
age: "34"
},
{
salary: "50001",
age: "35"
}
];
var result = $.extend(true, collection1, collection2);
console.log(result);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>

MDN
The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.
How do I go about looping through this?
With Object.assign() in mind we can loop through it like below:
var data = [];
data[0] = {name:"Bob", model:"Tesla", color:"white"};
data[1] = {name:"Martin", model:"Ford", color:"Blue"};
data[2] = {name:"Danny", model:"BMW", color:"Purple"};
var new_data =[];
new_data[0] = {salary:"50000", age:"34"};
new_data[1] = {salary:"45000", age:"24"};
new_data[2] = {salary:"10000", age:"39"};
for(var i = 0; i < data.length; i++){
data[i] = Object.assign(data[i], new_data[i]);
console.log(data[i]);
}

You can use jQuery.extend function like shown below. It extends existing data[i] object with properties from new_data[i] object.
for ( var i = 0; i<data.length; i++ ) {
jQuery.extend(data[i], new_data[i]);
}

The most efficient way is to loop through every element in new_data and apply it to data.
for(var key in new_data[0]){
data[0][key] = new_data[0][key];
}

What you need to use if Object.assign like so :
for ( var i = 0;i < data.length; i++ ) {
Object.assign(data[i], new_data[i]);
}
This will alter the content of data.
concat is meant to be used with arrays. It will append one (or more) array(s) at the end of another.
let people = ["Dan","Bob"];
people.concat(["Mike"]); // people is now ["Dan", "Bob", "Mike"]

You could utilize the keys of one of the object to merge the two. This would work in IE9 and up as well. If you need to guard against overriding a property in your base object then you could add a quick truthy check for that key before assigning in the forEach invocation.
var obj1 = {id:1, name: "bob"}
var obj2 = {dob: "2000101"};
Object
.keys(obj1)
.forEach(function(k){
obj2[k] = obj1[k];
});
console.log(obj2);

Related

Combining two arrays into an object

I have two arrays one with label date i.e [Date, Date, Date ...] and
the other with the actual date data i.e [2021-11-26, 2021-11-25, ...].
I want to combine these two arrays such that I get array of objects such as [ { Date: 2021-11-26}, {Date:2021-11-25}, {..}, ...].
I have tried these two methods
obj = {};
for (var i = 0, l = date_label.length; i < l; i += 1) {
obj[date_label[i]] = data_date[i]
}
console.log(obj);
and
_.zipObject(date_label, data_date);
However it only ends up giving me the last date of my data set, in an object data structure ie { Date: 1999-11-24}
The keys inside an object / associative array are unique. Your obj is such a thing. If you turn it into a regular array and push new objects into it, it will work.
const obj = [];
for (let i = 0, l = date_label.length; i < l; i++) {
obj.push({[date_label[i]]: data_date[i]})
}
console.log(obj);
You should probably assert that both your arrays have the same length.
The issues you are facing is that your date_label are the same and the loop are replacing the dates on the same label, again and again, you just need to change the label name and give unique to each one or you change them into the loop as well like this (obj[date_label[i] + str(i)] = data_date[i]).
date_label = ['date1', 'date2', 'date3', .....]
obj = {};
for (var i = 0, l = date_label.length; i < l; i += 1) {
obj[date_label[i]] = data_date[i]
}
console.log(obj);
obj is of type array not object.
data_date needs to be in string format.
for(var i= 0; i<data_date.length-1;i++) {
obj.push({"Date":date_date[i]}) }
with array reduce
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
var myFinalArray = data_date.reduce(
(previousValue, currentValue, currentIndex, array) => ({
currentValue: date_label[currentIndex]
}), {});
Hello AshleyCrasto,
Welcome to Stackoverflow.
Sol : Well, the other members have given solution on how to achieve the desired result. I will emphasize on why you are getting the single object.
it only ends up giving me the last date of my data set, in an object data structure ie { Date: 1999-11-24}
You need to understand how references work in JavaScript. Heres the catch,
As the values in date_label are all same
[Date, Date, Date ...]
When you use,
obj[date_label[i]] = data_date[i]
Everytime, it get executed the same key value will be keep updating instead of creating new key and new value. Because the same values holds same reference.
So, first time {"date" : "somevalue"} will be there, then
second time {"date" : "somevalue2"}, the value of key "date" will be updated
with new value. This is due to same key.
Therefore, you need to take of this thing. For your better understanding here is my code: (same as others but elaborately)
const date_label = ["date","date"]
const data_date = [2021-11-26, 2021-11-25]
function returnObj(label, value){
//this will return a new object with provided label and value.
const Obj = {};
Obj[label] = value
return Obj
}
let listOfObjects = []
for(let i=0 ; i< date_label.length ; i++){
//new object will be added to list.
const obj = returnObj(date_label[i],data_date[i])
listOfObjects.push(obj)
}
console.log(listOfObjects)

Insert a new object in Array of object

I have an Array List.
dataList = []
I want to insert object in array, So I tried this,
dataList.concat([{"name":"BOB", "value":"1"}])
// [{"name":"BOB", "value":"1"}]
but when I insert 2nd object in the same array.
dataList.concat([{"name":"Joe", "value":"2"}])
// [{"name":"Joe", "value":"2"},{"name":"Joe", "value":"2"}]
after inserting second array it replaces first object also.
where am I wrong?, Please help.
Simply use push function
var dataList = [];
dataList.push({
"name": "BOB",
"value": "1"
});
//Pushing second object
dataList.push({
"name": "Joe",
"value": "2"
})
console.log(dataList)
To push a value in an array, you will have to use array.push. array.concat does not adds new item. it merges 2 array and return a third array. So your code:
dataList.concat([{"name":"BOB", "value":"1"}])
does not do anything.
var dataList = []
dataList.concat([{"name":"BOB", "value":"1"}])
console.log(dataList)
As per the behavior, your code should look something like this:
var dataList = []
var obj = [{"name":"BOB", "value":"1"}];
dataList = dataList.concat(obj)
obj[0].value = 2;
dataList = dataList.concat(obj)
console.log(dataList)
The reason both the objects are being affected is because, objects are copied/assigned using reference. So a variable will hold a memory location and any changes to it will be reflected to this location. So if you have more than 1 variable holding this reference, it will also get updated.
So how should you achieve this?
var dataList = []
var obj = {"name":"BOB", "value":"1"};
dataList = dataList.concat(obj)
var obj2 = Object.assign({}, obj)
obj2.value = 2;
dataList = dataList.concat(obj2)
console.log(dataList)
But still using Array.concat is wrong. It is not intended to be used like this.
var dataList = []
var obj = {"name":"BOB", "value":"1"};
dataList.push(obj)
var obj2 = Object.assign({}, obj)
obj2.value = 2;
dataList.push(obj2)
console.log(dataList)
References:
How to append something to an array?
Why does changing an Array in JavaScript affect copies of the array?
How do I correctly clone a JavaScript object?
Object.assign - MDN

JavaScript Array / Struct

I would like to create a structure within javascript. I have a pair of informations, I would like to use, example:
array[1] = new Struct();
array[1].name = "parameter-name";
array[1].value = "parameter-value";
array[2] = new Struct();
array[2].name = "parameter-name2";
array[2].value = "parameter-value2";
This can be on a diffrent page with diffrent values, maybe on element within my array, maybe 2-20..
Later, within my generic javascript, I would like to parse the array and continue with my parameters, example:
for(i=1 to length_of_my_array) {
_tag.array[i].name = array[i].value;
}
How can I realize this with pure javascript? Thanks for any hint!
As long as you don't want any fancy features, it's really easy to create such structures in JavaScript. In fact, the code you posted will almost work, if you replace the new Struct() with this:
array[1] = {};
This creates an empty object, and you can put any properties you want in it, such as name and value.
To create an array, you can do something like this:
var array = []; // empty array
// object literal notation to create your structures
array.push({ name: 'abc', value: 'def' });
array.push({ name: 'ghi', value: 'jkl' });
...
And to iterate over the array:
for (var i = 0; i < array.length; i++) {
// use array[i] here
}
It would be good to find out more regarding the problem you are attempting to resolve.
I don't think there is an object in JavaScript called Struct, unless you define one.
I think what you are looking for is a JavaScript object instead of Struct. There are a number of ways to create a new object, and they can be nested in an array or in other objects.
myArray[0] = new Object();
myArray[0].name = "parameter-name";
myArray[0].value = "parameter-value";
myArray[1] = new Object();
myArray[1].name = "parameter-name2";
myArray[1].value = "parameter-value2";
Notice that I have changed your code in a couple of ways:
1. "array" is named "myArray" to clarify that we are referring to a particular array.
2. The first instance of myArray is 0. Arrays start at 0 in Javascript.
3. Struct is changed to Object.
myarray = [
{
"name":"parameter-name",
"value":"parameter-value"
},
{
"name":"parameter-name2",
"value":"parameter-value2"
}
];
This is an alternative syntax for doing the same thing. It uses "literal notation" to designate an array (the square brackets), and the objects (the curly brackets).
for(var i = 0; i < myArray.length; i++) {
for(key in myArray[i]) {
alert(key + " :: " myArray[i][key]);
}
}
This will loop over the array and alert you for each property of the object.
alert(myArray[0]['value']) //parameter-value
myArray[0]['value'] = "bar";
alert(myArray[0]['value']) //bar
Each property of each object can also be assigned a new value.
You can define arrays and generic objects in pure JavaScript/json:
var array = []; // empty array
array.push({name: 'parameter-name', value: 'parameter-value'});
array.push({name: 'parameter-name2', value: 'parameter-value2'});
console.log(array);
// Output:
// [Object { name="parameter-name", value="parameter-value2"}, Object { name="parameter-name2", value="parameter-value2"}]
You can also define the same array like so:
var array = [
{name: 'parameter-name', value: 'parameter-value'},
{name: 'parameter-name2', value: 'parameter-value2'}
];
As far as looping through the array:
for (var i = 0; i<array.length; i++) {
var elem = array[i];
console.log(elem.name, elem.value);
}
// Outputs:
// parameter-name parameter-value2
// parameter-name2 parameter-value2
I'd store object literals in the array, like so:
var myArray = [];
myArray[0] = {name:"some name", value:"some value"};
myArray[1] = {name:"another name", value:"another value"};
for (i=0; i < myArray.length; i++) {
console.log(myArray[i].name + ' / ' + myArray[i].value);
}
// initialize empty array
var myArray = [];
// fill it with an object - the equivalent of a struct in javascript
myArray.push({
name: 'example-name'
value: 'example-value'
});
// repeat as neccessary
// walking through the array
for (var i = 0; i < myArray.length; i++)
{
// retrieving the record
record = myArray[i];
// and accessing a field
doSomething(record.name);
}
var array = {paramName: 'paramValue', paramName2: 'paramValue2'};
for(i in array) {
_tag.i = array.i;
}
There is no "Struct" in JavaScript only Object
my_array = new Array();
my_array.push({name: 'john', age:31});
my_array.push({name: 'da_didi', age:120});
for (i=0; i<my_array.length; i++)
{
alert(my_array[i].name);
}
How about
function Struct(name, value) {
this.name = name;
this.value = value;
}
arr[0] = new Struct("name1", "value1");
Javascript objects are loose objects: properties can be added and removed dynamically. So making a new Struct(), as you suggest, does -not- guarantee that the returned object will always have the properties you expect it to have. You have to check the availability of properties at the point of usage (duck typing):
var i, element;
for (i = 0; i < array.length; i++) {
element = array[i];
if (Object.hasOwnProperty.call(element, "name")
&& Object.hasOwnProperty.call(element, "value")) {
_tag[element.name] = element.value;
}
}
(Also, I'm just guessing that _tag is an object itself, but that wasn't clear from your example.)
You could probably use a more succinct syntax, but that depends heavily on the values of the properties. For example, you -might- be able to use something like this:
var i, element;
for (i = 0; i < array.length; i++) {
element = array[i];
if (element.name && element.value) {
_tag[element.name] = element.value;
}
}
But you need to realize that the above condition will be false not only if one or both of the properties (name and value) are undefined but also if the value of either or both refers to the empty string, null, 0, NaN, or false.

Does the Javascript 'for-in' function, return just an index?

This is a method I tried to run:
function SayHello() {
cars = new Array();
cars[0] = "Toyota";
cars[1] = "Mitsubishi";
cars[2] = "Honda";
for (car in cars) {
alert(car);
}
}
This returned:
0
1
2
When I changed the code to this:
function SayHello() {
cars = new Array();
cars[0] = "Toyota";
cars[1] = "Mitsubishi";
cars[2] = "Honda";
for (car in cars) {
alert(cars[car]);
}
}
It returned the names correctly.
My question is, does the for-in loop just return an index in an orderly fashion? Thanks.
Yes, the value of the iterator is the name of the property. It's highly frowned upon to use it to loop over arrays, however. For example, consider this:
x = ['a', 'b', 'c'];
x.foo = 'bar';
for (i in x) alert(i); // 0, 1, 2, foo
It's intended for iterating over the members of an object:
x = { a : 'apple', b : 'banana', c : 'carrot' };
for (i in x) {
// and it's best to check that the property actually exists
// on this object, not just on one of its prototypal ancestors:
if (x.hasOwnProperty(i)) {
alert(i); // 'a', 'b', 'c'
}
}
More information about why on the YUI Blog
Yes, it will be the index within the collections.
See here:
var mycars = ["Saab", "Volvo", "BMW"];
for (var car in mycars)
{
document.write(mycars[car] + "<br />");
}
As you can see, the use of the variable as an index into the collection.
You can use for each ... in syntax (introduced in Javascript 1.6) that will iterate over values. See here.
for each...in - similar to for...in, but iterates over the values of object's properties, rather than the property names themselves. (New in JavaScript 1.6.)
As far as I know, Javascript 1.6+ is only used in Firefox at this time.
Yes and no. It returns indexes, not the values, and it returns them as quoted strings. "0", "1", etc..
The plus side of this is that for in works the same if you use a javascript object as associative array.
It returns the "key" of each item. Same result will be achieved with such "array":
cars = {0: "Toyota", 1: "Mitsubishi", 2: "Honda"};
use the regular for...
for (var i = 0; i < cars.length; i++) {
let car = cars[i];
// Do what you want from here
}
for...in - iterates over all enumerable properties of an object that are keyed by strings (for simple arrays it returns the element's index).
for...of - iterates over the property values but can only be used for iteratable types: built-in String, Array, array-like objects (e.g., arguments or NodeList), TypedArray, Map, Set, and user-defined iterables (not for generic objects).

Group javascript items by one property

My question is related to this question. You will have to first read it.
var ids = "1*2*3";
var Name ="John*Brain*Andy";
var Code ="A12*B22*B22";
Now that I have an array of javascript objects. I want to group my objects based on CODE. So there can be duplicate codes in that code string.
As per the above changed strings, I have same code for Brain and Andy. So, now I want two arrays. In one there will be only one object containing details of only John and in the other object there will be two objects containing details of Brain and Andy.
Just for example I've taken 3 items. In actual there can be many and also there can be many set of distinct codes.
UPDATE
I needed the structure like the one built in groupMap object by the #Pointy. But I will use #patrick's code to achieve that structure. Many thanks to both of them.
It is a little hard to tell the exact resulting structure that you want.
This code:
// Split values into arrays
Code = Code.split('*');
Name = Name.split('*');
ids = ids.split('*');
// cache the length of one and create the result object
var length = Code.length;
var result = {};
// Iterate over each array item
// If we come across a new code,
// add it to result with an empty array
for(var i = 0; i < length; i++) {
if(Code[i] in result == false) {
result[ Code[i] ] = [];
}
// Push a new object into the Code at "i" with the Name and ID at "i"
result[ Code[i] ].push({ name:Name[i], id:ids[i] });
}
Will produce this structure:
// Resulting object
{
// A12 has array with one object
A12: [ {id: "1", name: "John"} ],
// B22 has array with two objects
B22: [ {id: "2", name: "Brain"},
{id: "3", name: "Andy"}
]
}
Split the strings on "*" so that you have 3 arrays.
Build objects from like-indexed elements of each array.
While building those objects, collect a second object that contains arrays for each "Code" value.
Code:
function toGroups(ids, names, codes) {
ids = ids.split('*');
names = names.split('*');
codes = codes.split('*');
if (ids.length !== names.length || ids.length !== codes.length)
throw "Invalid strings";
var objects = [], groupMap = {};
for (var i = 0; i < ids.length; ++i) {
var o = { id: ids[i], name: names[i], code: code[i] };
objects.push(o);
if (groupMap[o.code]) {
groupMap[o.code].push(o);
else
groupMap[o.code] = [o];
}
return { objects: objects, groupMap: groupMap };
}
The "two arrays" you say you want will be in the "groupMap" property of the object returned by that function.

Categories