Fetch data from a nested array - javascript

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);

Related

Extracting a data from json array by certain key in java script

I have a json array which im getting my react data from it,
the json is like this:
{
"Folders": [
{
"name": "parent 2",
"children": [ //this is children_1
{
"name": "parent 2",
"id": "parent 2",
"children": [] //this is children_2
}
],
"id": 1
}
]
}
lets say i have the key value of name inside children(children_1) and i want to get the rest of the data inside that children using the name that i have, is there a way to do that ?
Look at jsonpath
so it will be
var json = require('jsonpath');
var names = jp.query(json, '$.Folders[*].children[*].children');

Issues with converting an array of objects into a different format

I'm struggling to convert an array that I've been given into a useful format:
Given
{
"myValues": [{
"0": {
"id": "5ed32599-3c4d-49ad-8a1a-79bbc39a3e02",
"value": "my Value",
"value2": "my Value 2"
},
"1": {
"id": "5ed32599-3c4d-49ad-8a1a-79bbc39a3e02",
"value": "my Value",
"value2": "my Value 2"
},
"id": "5ed32599-3c4d-49ad-8a1a-79bbc39a3e02"
}]
}
I am trying to remove the numbers in front of the objects and just the ID that sits outside of the two inner objects.
Therefore I would then be given:
{
"myValues": [{
"id": "5ed32599-3c4d-49ad-8a1a-79bbc39a3e02",
"value": "my Value",
"value2": "my Value 2"
},
{
"id": "5ed32599-3c4d-49ad-8a1a-79bbc39a3e02",
"value": "my Value",
"value2": "my Value 2"
}
]
}
I have been trying to use different ways of mapping Objects into new formats but I'm really struggling particularly to get rid of the IDs
You can use Object.values().
I added a filter() to remove the single id...not sure if that is a typo in example data or not...or if you also want it included in results
const myValues=[
{
"0":{
"id":"5ed32599-3c4d-49ad-8a1a-79bbc39a3e02",
value : 'my Value',
value2 : 'my Value 2'
},
"1":{
"id":"5ed32599-3c4d-49ad-8a1a-79bbc39a3e02",
value : 'my Value',
value2 : 'my Value 2'
},
"id":"5ed32599-3c4d-49ad-8a1a-79bbc39a3e02"
}
]
const arrValues = Object.values(myValues[0]).filter(el => typeof el === 'object')
console.log(arrValues)

JSON Objects in a JSON Array in 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;
}

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"}
}
}
])

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