Add data to object array in javascript - javascript

I know I can do something like that:
var data = [
{
name: 'test1',
value: 1
}
];
But I want to fill data with dynamic values (from HTML). So I will have var data = []; and how can I fill this one? I know, it must be somewhere on the internet, but I don not know the "right words" to search.
Note: data have to be array filled with objects.

You can use the 'push' method.
var a = [];
a.push({item: 'a', value : 'a'});
console.log(a);

You can use .push method, like so
var data = [];
data.push({ name: 'test1', value: 1});
data.push({ name: 'test2', value: 2});
data.push({ name: 'test3', value: 3});
console.log(data);

Related

Change order of object properties based on array with indices (JavaScript)

I've been really struggling with this piece of code.
I have an object that goes like:
var obj = {
Name: 'Test',
Id: 1,
Address: 'addr'
}
And an array that goes like:
var arr = [1,0,2];
I want the properties of the object to be sorted with the indices given in the second one.
The result should then be something like:
var obj = {
Id: 1,
Name: 'Test',
Address: 'addr'
}
I'm really looking forward to your replies.
You cannot reliably set the order of the properties in an object. You will need to rethink your approach to this problem so that the order is handled by an array, not an object. The array can then be used to write code that accesses properties in a specific order, even though the object doesn't actually have them in that order.
For example:
const columns = ['Id', 'Name', 'Address'];
const data = [{
Name: 'Test',
Id: 1,
Address: 'addr'
}, {
Address: 'addr2',
Id: 1,
Name: 'Test2',
}];
let csv = columns.join(',') + '\n';
data.forEach(obj => {
const row = columns.map(propertyName => {
return obj[propertyName];
});
csv = csv + row.join(',') + '\n'
})
console.log(csv);

filtering an array of object based on string array

my problem might not be as challenging as some other similar questions but they were a little to much for me.
I have an array of objects that I need to filter by name against a string array of names, if the names match I want to remove the object with the name that matches
so like the following:
nameObjects = [{name: 'name3', value: 'some val'},{name: 'name1', value:'some other val'}]
names = ['name1','name2','name3']
I've tried the following just using for loops but I'm sure that there is a quicker (and correct lol) filter method that works
for(i=0; i < this.names.length; i++){
for(j=0; j < this.nameObjects.length; j++){
if(this.names[i] === this.nameObjects[j].name){
this.files.splice(i,this.nameObjects[j])
}
}
}
also sorry for the poor logic ^
You should not mutate the array while you are looping over it.
You can simply use Array.prototype.filter with Array.prototype.includes to get the desired result
const nameObjects = [{name: 'name3', value: 'some val'},{name: 'name1', value:'some other val'}];
const names = ['name2','name3'];
const res = nameObjects.filter(obj => !names.includes(obj.name));
console.log(res);
const nameObjects = [
{ name: "name3", value: "some val" },
{ name: "name1", value: "some other val" },
];
const names = ["name1", "name2"];
const result = nameObjects.filter(obj => !names.includes(obj.name));
console.log(result);

Old JSON value Changed

I have two JSON objects columnsData and columns when assigning columnsData value to columns both values are changed.
var columnsData = [
{id: "id"},
{id: "root_task_assignee"},
{id: "root_task_id"},
{id: "root_task_status"},
{id: "root_task_tracker"},
{id: "rt_category"},
{id: "rt_priority"},
{id: "rt_subject"},
]
var columns = [];
using the below function I assigned the columnsData value to columns object, and also added some additional fields
for(i = 0;i < columnsData.length; i++){
columns[i] = columnsData[i];
columns[i]["name"] = columnsData[i]["name"] || columnsData[i]["id"];
columns[i]["type"] = columnsData[i]["id"]["type"] || "string";
}
but after assigning both have the same values. How the old JSON columnsData value was changed? is there any other way to assign values
columns[i] = columnsData[i] does not copy the data, it makes an additional reference to the same data.
For example, say you give Mr. Random Jones a nickname, "Cozy". If you give Cozy an envelope to hold, are you surprised if Mr. Jones is now holding an envelope too?
Same thing here. If you change columns[i], you are also changing columnsData[i], since they are the same object.
You would have to clone it if you wanted to have them be different. In this case, you just have to make a new object with id:
columns[i] = { id: columnsData[i].id };
In general, you would do well to find a nice clone function.
If it is required to keep original array pure (unchanged) we should use map method of array.
var columnsData = [
{id: "id"},
{id: "root_task_assignee"},
{id: "root_task_id"},
{id: "root_task_status"},
{id: "root_task_tracker"},
{id: "rt_category"},
{id: "rt_priority"},
{id: "rt_subject"},
]
var columns = columnsData.map(function(obj){
var rObj = {};
rObj[obj.key] = obj.value;
rObj["name"] = obj.value;
.....
return rObj;
});
Logic can be added in map method to create new array as required. Hope it helps.
columns[i] = columnsData[i] will not copy content from one object to another but it will an reference of the columnsData[i]. As they are refereeing to same object, change in property of one object will affect the primary object which is being refereed.
Try this:
var columnsData = [{
id: "id"
}, {
id: "root_task_assignee"
}, {
id: "root_task_id"
}, {
id: "root_task_status"
}, {
id: "root_task_tracker"
}, {
id: "rt_category"
}, {
id: "rt_priority"
}, {
id: "rt_subject"
}, ]
var columns = [];
for (i = 0; i < columnsData.length; i++) {
var obj = {};
obj["name"] = columnsData[i]["name"] || columnsData[i]["id"];
obj["type"] = columnsData[i]["id"]["type"] || "string";
columns.push(obj)
}
alert(JSON.stringify(columns));
alert(JSON.stringify(columnsData));

Get length of object by nested object id?

I'm currently using underscore to the length of an object using _.size(obj) and that is fine but I'm wondering how I could go a little deeper and get the length of objects who's id's equal 123 in my example. I'm not sure if this is something that can be achieved by using underscore or do I need to use a for..in loop and make some kind of count?
JS
console.clear();
var obj = {
'ABC': {
id: '123',
name: 'Sesame Street'
},
'DEF': {
id: '123',
name: 'Sesame Street'
},
'GHI': {
id: '456',
name: 'Nowhere Street'
}
};
console.log('Get length of obj', _.size(obj));
console.log('Get length of obj with id == 123??');
JSFiddle: http://jsfiddle.net/kyllle/0yam33ow/
You could convert your object into an array and use .filter to get the items with only the id 123:
var arr = _.values(obj);
var newObj = arr.filter(function(item){
return item.id === '123';
});
console.log(_.size(newObj)); // 2
You can do the same thing by using underscores _.where:
var newObj = _.where(obj, {id: '123'});
Fiddle Example

How do I get a specific object from an immutable js map by value?

I created an immutable map (with Immutable-JS) from a list of objects:
var result = [{'id': 2}, {'id': 4}];
var map = Immutable.fromJS(result);
Now i want to get the object with id = 4.
Is there an easier way than this:
var object = map.filter(function(obj){
return obj.get('id') === 4
}).first();
Essentially, no: you're performing a list lookup by value, not by index, so it will always be a linear traversal.
An improvement would be to use find instead of filter:
var result = map.find(function(obj){return obj.get('id') === 4;});
The first thing to note is that you're not actually creating a map, you're creating a list:
var result = [{'id': 2}, {'id': 4}];
var map = Immutable.fromJS(result);
Immutable.Map.isMap(map); // false
Immutable.List.isList(map); // true
In order to create a map you can use a reviver argument in your toJS call (docs), but it's certainly not the most intuitive api, alternatively you can do something like:
// lets use letters rather than numbers as numbers get coerced to strings anyway
var result = [{'id': 'a'}, {'id': 'b'}];
var map = Immutable.Map(result.reduce(function(previous, current) {
previous[ current.id ] = current;
return previous;
}, {}));
Immutable.Map.isMap(map); // true
Now we have a proper Immutable.js map which has a get method
var item = Map.get('a'); // {id: 'a'}
It may be important to guarantee the order of the array. If that's the case:
Use an OrderedMap
Do a set method on the OrderedMap at each iteration of your source array
The example below uses "withMutations" for better performance.
var OrderedMap = Immutable.OrderedMap
// Get new OrderedMap
function getOm(arr) {
return OrderedMap().withMutations(map => {
arr.forEach(item => map.set(item.id, item))
})
}
// Source collection
var srcArray = [
{
id: 123,
value: 'foo'
},
{
id: 456,
value: 'bar'
}
]
var myOrderedMap = getOm(srcArray)
myOrderedMap.get(123)
// --> { id: 123, value: 'foo' }
myOrderedMap.toObject()
// --> { 123: {id: 123, value: 'foo'}, 456: {id: 456, value: 'bar'} }
myOrderedMap.toArray()
// --> [ {id: 123, value: 'foo'}, { id: 456, value: 'bar' } ]
When using fromJS for array, you'll get List not map. It will be better and easier if you create a map. The following code will convert the result into Immutable map.
const map = result.reduce((map, json) =>
map.set(json.id, Immutable.fromJS(json))
, Map());
Now, you can
map.get('2'); //{'id': 2}
Note, if the result has nested structure and if that has array, it will be a List with the above code.
With ES2015 syntax (and constants):
const result = map.find(o => o.get('id') === 4);
Is there already a way thats easier? I don't know. but you can write your own function. Something like this should work:
var myFunc = function(id){
var object = map.filter(function(obj){return obj.get('id') === id}).first();
return object;
}
Then you would just do:
var myObj = myFunc(4);

Categories

Resources