JSON Objects in a JSON Array in javascript - javascript

I am playing around with JSON objects in JSON arrays. On click of a button, I push the json objects into a array like below:
jsonArray.push({
columnNameProperty: columnName,
columnValueProerty: columnValue,
id: column.id
});
My resulted array looks like this:
[
0:{
columnNameProperty: "Name",
columnValueProperty: "Nancy",
id: "123"
},
1:{
columnNameProperty: "Name",
columnValueProperty: "Jene",
id: "124"
},
2:{
columnNameProperty: "Amount",
columnValueProperty: "1000",
id: "123"
},
3:{
columnNameProperty: "State",
columnValueProperty: "WA",
id: "123"
}
]
How do I modify this as I want to push items based on the id.
[
"123" : {
"Name" : "Nancy",
"Amount" : "1000",
"State" : "WA"
},
"124" : {
"Name" : "Jene"
}
]
Anyone could suggest me how to structure it in this format.

#Amy is correct, that is not in fact valid javascript. Arrays do not have keys. So your example
[
0:{
columnNameProperty: "Name",
columnValueProperty: "Nancy",
id: "123"
},
1:{
columnNameProperty: "Name",
columnValueProperty: "Jene",
id: "124"
}
]
really looks like this
[
{
columnNameProperty: "Name",
columnValueProperty: "Nancy",
id: "123"
},
{
columnNameProperty: "Name",
columnValueProperty: "Jene",
id: "124"
}
]
If your goal is to retrieve an element by id you could make a function that loops through the array, finds and returns the object with the given id.
Alternatively, you could create a hash map and access each values by its key. So for instance, given this object:
let map = {
"123" : {
"Name" : "Nancy",
"Amount" : "1000",
"State" : "WA"
},
"124" : {
"Name" : "Jene"
}
}
You could get the value of the key "123" by saying map['123']

Why do you have to use an array? For what you are trying to achieve you can set up a object and then just insert more objects into it.
var exampleObject={};
function onClick(){
exampleObject["123"]={"Name":"steve"}
}
I assume you are trying to use that approach to later find the right object in the array?
You can simply loop over the object and find it in there:
for (var obj in exampleObject){
if(obj==="123"){
//do something
}
}

Was able to achieve the required format by creating HashMap/Object:
var id = column.id;
var mapObject = {}, editMap = {};
if(editMap.hasOwnProperty(id)){
mapObject = editMap[id];
mapObject[columnName] = grid[columnName];
editMap[id] = mapObject;
}
else{
mapObject[columnName] = [columnName];
editMap[id] = mapObject;
}

Related

How to Push Value to an Array Inside an Object

I have an array inside an Object which looks like this.
sourceSystemArray = [{
"attId" : 2257,
"attributeName" : "country",
"attributeValues" : [ "AU", "KG", "IN", "AF" ]
}]
Using input field I give user option to add a new Value.
Now I would like to finally add the New Input value that I get using ngModel to attributeValues array.
So suppose user enters a new Country say NZ.
So I want to push NZ to attributeValues and my final Object should like this:
sourceSystemArray = [{
"attId" : 2257,
"attributeName" : "country",
"attributeValues" : [ "AU", "KG", "IN", "AF","NZ" ]
}]
I tried using push method but it's not working.
Can someone help me figure out how to achieve it.
If you're trying to add this object you might be having problems because it's in an array itself. Here's how I would add to attributeValues.
let myarray = [{
"attId" : 2257,
"attributeName" : "country",
"attributeValues" : [ "AU", "KG", "IN", "AF" ]
}]
myarray[0].attribute values.push('GB')
Or, assuming it's not the only item in the array.
let myarray = [{
"attId" : 2257,
"attributeName" : "country",
"attributeValues" : [ "AU", "KG", "IN", "AF" ]
}]
myarray.find(item => item.attId === 2257)
.attributeValues.push('GB')
Since sourceSystemArray is an array, try this
sourceSystemArra[0].attributeValues.push("NZ");
in html part u should send both attId and your new value with function
then in component u should find method with attId
function(attId,newValue){
this.sourceSystemArray.find(data=>data.attId ==attId).attributeValues.push(newValue);
}

Fetch data from a nested array

I would like to know if there is a way to get the length from a nested array.
My data is a JSON file like this:
{
"data" :[
"item1" :'',
"item2" :[{
"id" :1,
"text":'text'
},{
"id" :2,
"text" : 'text
}]
]
}
I'm using angular 6 and ngx-restangular.
Is possible to get the item 2 length?
The main problem is the question does not provide a valid json. A valid json for the same would be like as under :
{
"data": {
"item1": "",
"item2": [{
"id": 1,
"text": "text"
},
{
"id": 2,
"text": "text"
}
]
}
}
Now you can fetch the second element size simply by
data["item2"].length
or
data.item2.length
To extend the Answer from #AurA
If you had to work with a valid array:
[
[ "item0.0", "item0.1" ],
[ "item1.0", "item1.1" ]
]
you could access the length of the nested arrays like this:
let a = [
["item0.0", "item0.1"],
["item1.0", "item1.1"]
];
let lengthA0 = a[0].length;
let lengthA1 = a[1].length;
console.log("length of a0: ", lengthA0);
console.log("length of a1: ", lengthA1);

MongoDB query for latest data?

Pretty much my data looks something like this:
{
"name" : "Name1",
"monthson" : "4",
"data" : "OLD DATA FOR 1"
},
{
"name" : "Name1",
"monthson" : "5",
"data" : "LATEST DATA FOR 1"
},
{
"name" : "Name2",
"monthson" : "7",
"data" : "OLD DATA FOR 2"
},
{
"name" : "Name2",
"monthson" : "8",
"data" : "LATEST DATA FOR 2"
}
I'm trying to figure out a way to group everything by each name and then output the latest Data. (monthson represents how many months each set has been active so the highest monthson is the most recent).
My Mongo query looks something like this:
db.collection.aggregate(
[
{$match: {$in: ["name1", "name2"]}}
{$group:
{
_id:"$name",
monthson:{$max: "$monthson"},
data: {$addToSet: "$data"}
}},
])
The output looks like this:
{
_id:"Name1",
monthson: 5,
data: ["OLD DATA FOR 1", " LATEST DATA FOR 1"]
}
{
_id:"Name2",
monthson: 8,
data: ["LATEST DATA FOR 2", "OLD DATA FOR 2"]
}
The trick is every time I run this query it adds every set of data to my result when I only want the data that corresponds to the highest monthson. I can't query for first, last or highest data because they will always be in random order.
You can use $sort to get the order you want (I used oldest first), and then $first to get to the first (oldest) matching record for each "name":
db.collection.aggregate([
{
$match: {name: {$in: ["Name1", "Name2"]}}
},
{
$sort: {monthson:-1}
},
{
$group: {
_id:"$name",
first:{$first: "$$ROOT"}
}
}
])

Rename variables at different levels of nested JSON dataset

I am looking to rename a variable with a different name depending on its level within a nested JSON dataset.
An example JSON file is the following:
[
{
key: "John Doe School",
values: [
{
key: "Mr. Brown",
values: [
{
key: "Joe",
TestScore: 95
},
{
key: "Sarah",
TestScore: 99
}
]
}
]
}
]
In this example, I would like to change the first-level "key" to "School", the second-level "key" to "Teacher", and the third-level "key" to "Student".
The JSON dataset would look like this following the changes:
[
{
School: "John Doe School",
values: [
{
Teacher: "Mr. Brown",
values: [
{
Student: "Joe",
TestScore: 95
},
{
Student: "Sarah",
TestScore: 99
}
]
}
]
}
]
Well, given your example, you could just do this...
var json = [
{
key: "John Doe School",
values: [
{
key: "Mr. Brown",
values: [
{
key: "Joe",
TestScore: 95
},
{
key: "Sarah",
TestScore: 99
}
]
}
]
}
];
json[0].key = "School";
json[0].values[0].key = "Teacher";
json[0].values[0].values[0].key = "Student";
json[0].values[0].values[1].key = "Student";
UPDATE FOLLOWING COMMENT
json[0]['School'] = json[0].key; // Add new key:value
delete json[0].key; // Delete previous one
json[0].values[0]['Teacher'] = json[0].values[0].key; // Add new key:value
delete json[0].values[0].key; // Delete previous one
json[0].values[0].values[0]['Student'] = json[0].values[0].values[0].key; // Add new key:value
delete json[0].values[0].values[0].key; // Delete previous one
json[0].values[0].values[1]['Student'] = json[0].values[0].values[1].key; // Add new key:value
delete json[0].values[0].values[1].key; // Delete previous one
I assume you will be looping through a number of different JSON objects however, so you would of course also need to implement that but the above structure should point you in the right direction ;)

MongoDB : Map Reduce : Create one sub-document from another one

I have a mongodb collection which has documents like this :
{
"_id" : ObjectId("safdsd435tdg54trgds"),
"startDate" : ISODate("2013-07-02T17:35:01.000Z"),
"endDate" : ISODate("2013-08-02T17:35:01.000Z"),
"active" : true,
"channels" : [
1, 2, 3, 4
],
}
I want to convert this to something like this :
{
"_id" : ObjectId("safdsd435tdg54trgds"),
"startDate" : ISODate("2013-07-02T17:35:01.000Z"),
"endDate" : ISODate("2013-08-02T17:35:01.000Z"),
"active" : true,
"channels" : [
1, 2, 3, 4
],
"tags" :[
{
"name": one
"type": channel
},
{
"name": two
"type": channel
},
{
"name": three
"type": channel
},
{
"name": four
"type": channel
}
]
}
I already have a mapping of what 1,2,3,4 mean. Just for the sake of simplicity I put them as their alphabetical format. the values could be different, but they're static mappings.
You seem to be trying to do this update without a big iteration of your collection, So you "could" do this with mapReduce, albeit in a very "mapReduce way" as it has it's own way of doing things.
So first you want to define a mapper that encapsulates your current document :
var mapFunction = function (){
var key = this._id;
var value = {
startDate: this.startDate,
endDate: this.endDate,
active: this.active,
channels: this.channels
};
emit( key, value );
};
Now here the reducer is actually not going to be called as all the keys from the mapper will be unique, being of course the _id values from the original document. But to make the call happy:
var reduceFunction = function(){};
As this is a one to one thing this will go to finalize. It could be in the mapper, but for cleanliness sake
var finalizeFunction = function (key, reducedValue) {
var tags = [
{ name: "one", type: "channel" },
{ name: "two", type: "channel" },
{ name: "three", type: "channel" },
{ name: "four", type: "channel" }
];
reducedValue.tags = [];
reducedValue.channels.forEach(function(channel) {
reducedValue.tags.push( tags[ channel -1 ] );
});
return reducedValue;
};
Then call the mapReduce:
db.docs.mapReduce(
mapFunction,
reduceFunction,
{
out: { replace: "newdocs" },
finalize: finalizeFunction
}
)
So that will output to a new collection, but in the way that mapReduce does it so you have this:
{
"_id" : ObjectId("53112b2d0ceb66905ae41259"),
"value" : {
"startDate" : ISODate("2013-07-02T17:35:01Z"),
"endDate" : ISODate("2013-08-02T17:35:01Z"),
"active" : true,
"channels" : [ 1, 2, 3, 4 ],
"tags" : [
{
"name" : "one",
"type" : "channel"
},
{
"name" : "two",
"type" : "channel"
},
{
"name" : "three",
"type" : "channel"
},
{
"name" : "four",
"type" : "channel"
}
]
}
}
So all your document fields other than _id are stuck under that value field, so that's not the document that you want. But that is how mapReduce works.
If you really need to get out of jail from this and are willing to wait a bit, the upcoming 2.6 release has added an $out pipeline stage. So you "could" transform the documents in your new collection with $project like this:
db.newdocs.aggregate([
// Transform the document
{"$project": {
"startDate": "$value.startDate",
"endDate": "$value.endDate",
"active": "$value.active",
"channels": "$value.channels",
"tags": "$value.tags"
}},
// Output to new collection
{"$out": "fixeddocs" }
])
So that will be right. But of course this is not your original collection. So to back to that state you are going to have to .drop() collections and use .renameCollection() :
db.newdocs.drop();
db.docs.drop();
db.fixeddocs.renameCollection("docs");
Now please READ the documentation carefully on this, there are several limitations, and of course you would have to re-create indexes as well.
All of this, and in particular the last stage is going to result in a lot of disk thrashing and also keep in mind that you are dropping collections here. It almost certainly is a case for taking access to your database off-line while this is performed.
And even as such the dangers here are real enough that perhaps you can just live with running an iterative loop to update the documents, using arbitrary JavaScript. And if you really must have to do so, you could always do that using db.eval() to have that all execute on the server. But if you do, then please read the documentation for that very carefully as well.
But for completeness even if I'm not advocating this:
db.eval(function(){
db.docs.find().forEach(function(document) {
var tags = [
{ name: "one", type: "channel" },
{ name: "two", type: "channel" },
{ name: "three", type: "channel" },
{ name: "four", type: "channel" }
];
document.tags = [];
document.channels.forEach(function(channel) {
document.tags.push( tags[ channel -1 ] );
});
var id = document._id;
delete document._id;
db.docs.update({ "_id": id },document);
});
})

Categories

Resources