How to fetch the length and individual values in javascript
here is example data
examples:
"numbers": "248001,248142",
"numbers": "588801,248742,588869"
Actuall code
{
"_id" : ObjectId("579ce69f4be1811f797fbab2"),
"city" : "",
"sdescription" : "",
"categories" : [
"5729f312d549cc3212c8393b"
],
"numbers" : "4555855,421201",
"createdAt" : ISODate("2016-07-30T17:40:47.022Z"),
"month" : 7,
"year" : 2016
}
here is my code and error
let num = numbers.split(',')
(node:5628) UnhandledPromiseRejectionWarning: TypeError: numbers.split is not a function
I have tried split to separate the values but some times it returns an error as number.split is not a function.
I want to return two things:
length: in the first example length should be 2 and in the second example
length should be 3.
2.values should get split
You need to call start from object name objectname.keyname
var obj = { "city": "", "sdescription": "", "categories": [ "5729f312d549cc3212c8393b" ], "numbers": "4555855,421201", "month": 7, "year": 2016 }
var res = obj.numbers.split(',').length;
console.log(res)
You can loop through your object and then for each element access numbers property and then split and find length
let json = [{"numbers": "248001,248142"},{"numbers": "588801,248742,588869"},{"numbers":[]}]
json.forEach(({numbers})=>{
console.log(typeof numbers === 'string' ? numbers.split(',').length : 'Not a string')
})
Related
hello i need help with array , as you can see my data
{
"age" : "18",
"altKategoriler" : [ "Dramalar" ],
"category" : [ "Aksiyon", "Heyecanlı", "Gerilim" ],
"id" : 5240718100,
"img" : "https://i.ibb.co/k8wx5C8/AAAABW9-ZJQOg-MRljz-Zwe30-JZw-Hf4vq-ERHq6-HMva5-ODHln-Ci-OEV6ir-Rcjt88tcnm-QGQCKpr-K9h-Oll-Ln-Sbb-EI.jpg",
"izlenilmeSayisi" : 0,
"logo" : "https://i.ibb.co/Rb2SrcB/AAAABfcrhh-Rni-Ok-Ct2l-Rys-ZYk-Oi-T0-XTeagkrw-Mkm-U0h-Lr-WIQZHEHg-VXihf-OWCwz-Vv-Qd7u-Ffn-DFZEX2-Ob.webp",
"oyuncuKadrosu" : [ "Diego Luna", "Michael Pena", "Scoot McNairy", "Tenoch Huerta", "Joaquin Cosio" ],
"senarist" : [ "Doug Miro" ],
"time" : "3 Sezon",
"title" : "Narcos: Mexico",
"type" : "Dizi",
"videoDescription" : "Guadalajara Karteli'nin yükselişinin gerçek öyküsünü anlatan bu yeni ve cesur Narcos hikâyesinde, Meksika'daki uyuşturucu savaşının 1980'lerdeki doğuşuna tanıklık edin.",
"videoQuality" : "HD",
"videosrc" : "https://tr.vid.web.acsta.net/uk/medias/nmedia/90/18/10/18/19/19550785_hd_013.mp4",
"year" : "2021",
"yonetmen" : [ "Carlo Bernard", "Chris Brancato" ]
}
I can access elements such as id , title or logo because they are not arrays.
How can I loop through the data inside the array since there is an array in the category in yield?
var data = this.database.filter((item) => item.type == searchType)
var data = this.database.filter((item) => item.category == searchCategory)
It's okay because my type value doesn't have an array.
But when I enter my category value, it only gets the first index[0]. It does not look at other indexes.
in summary,
item.category[0] , item.category[1] , item.category[2]...........
How can I get index browsing like
if your data looks like this :
let data ={
"age" : "18",
"altKategoriler" : [ "Dramalar" ],
"category" : [ "Aksiyon", "Heyecanlı", "Gerilim" ],
"id" : 5240718100,
"img" : "https://i.ibb.co/k8wx5C8/AAAABW9-ZJQOg-MRljz-Zwe30-JZw-Hf4vq-ERHq6-HMva5-ODHln-Ci-OEV6ir-Rcjt88tcnm-QGQCKpr-K9h-Oll-Ln-Sbb-EI.jpg",
"izlenilmeSayisi" : 0,
"logo" : "https://i.ibb.co/Rb2SrcB/AAAABfcrhh-Rni-Ok-Ct2l-Rys-ZYk-Oi-T0-XTeagkrw-Mkm-U0h-Lr-WIQZHEHg-VXihf-OWCwz-Vv-Qd7u-Ffn-DFZEX2-Ob.webp",
"oyuncuKadrosu" : [ "Diego Luna", "Michael Pena", "Scoot McNairy", "Tenoch Huerta", "Joaquin Cosio" ],
"senarist" : [ "Doug Miro" ],
"time" : "3 Sezon",
"title" : "Narcos: Mexico",
"type" : "Dizi",
"videoDescription" : "Guadalajara Karteli'nin yükselişinin gerçek öyküsünü anlatan bu yeni ve cesur Narcos hikâyesinde, Meksika'daki uyuşturucu savaşının 1980'lerdeki doğuşuna tanıklık edin.",
"videoQuality" : "HD",
"videosrc" : "https://tr.vid.web.acsta.net/uk/medias/nmedia/90/18/10/18/19/19550785_hd_013.mp4",
"year" : "2021",
"yonetmen" : [ "Carlo Bernard", "Chris Brancato" ]
}
and if we have array of data you can do something like this :
myArray.filter(item=>item.category.indexOf(searchCategory)>=0)
but if you want to explore in object rather than array you can do this :
data.category.indexOf(searchCategory)>=0
You could make this a bit generic, by testing whether the targeted field is an array, using Array.isArray, and then call a filter on each element, and see if any is positive (using .some()). The filter can be function that is provided, so that it can perform a simple match, or apply a regular expression, or anything else.
Instead of testing with Array.isArray you could skip that step and check whether the value has a .some() method. If so, calling it will give the desired outcome, and otherwise (using the .? and ?? operators), the filter should be applied to the value as a whole:
Here is how that looks:
function applyFilter(data, field, filter) {
return data.filter(item => item[field]?.some(filter) ?? filter(item));
}
// Example use:
var data = [{
"category" : [ "Action", "Thriller", "Horror"],
"type" : "Series",
}, {
"category" : [ "Historical", "Romance" ],
"type" : "Theatre",
}];
// Find entries that have a category that looks like "roman*":
var result = applyFilter(data, "category", value => /^roman.*/i.test(value));
console.log(result);
If you are running on an older version of JavaScript, and don't have support for .? or ??, then use:
return data.filter(item => Array.isArray(item[field])
? item[field].some(filter)
: filter(item));
I got this sample data.
"array" : [
{"Id" : "1", "preferred" : false},
{"Id" : "1", "preferred" : true },
{"Id" : "2", "preferred" : false},
{"Id" : "2", "preferred" : false},]
And i would like to get out of it something like this.
"array2":[{"Id": 1, numOfTrue: 1, numOfFalse: 1},{"Id": 2, numOfTrue: 0, numOfFalse: 2}]
What i got so far is a way how to get unique id form initial array.
const unique = [...new Set(array.map(item => Id))];
Next step would be some forEach over array and comparing Id values and setting some counters for that boolean value. So before i dive into forEach solution i would like to ask if there is another way with using .filter() and .reduce() methods.
You can use reduce() to build a grouping object keyed to Id. Each time you see that Id again increment the value at the appropriate key. In the end your array will be the Object.values() of the object:
let array = [
{"Id" : "1", "preferred" : false},
{"Id" : "1", "preferred" : true },
{"Id" : "2", "preferred" : false},
{"Id" : "2", "preferred" : false}
]
let counts = array.reduce((counts, {Id, preferred}) => {
// If you haven't seen this Id yet, make a new entry
if (!counts[Id]) counts[Id] = {Id, numOfTrue: 0, numOfFalse: 0}
// increment the appropriate value:
if (preferred) counts[Id].numOfTrue++
else counts[Id].numOfFalse++
return counts
}, {})
// get the values array of the object:
console.log(Object.values(counts))
I'm new to robmongo and I received an assignment to write some queries.
let say I have a collection that each key has some values for example value of "userId" and value of "deviceModel".
I need to write a query that shows for each device model how many users has this device.
this is what I got so far:
db.device_data.aggregate([ {"$group" : {_id:"$data.deviceModel", count:{$sum:1}}}])
The problem is that this aggregate for each device the number of keys it appears.
{
"_id" : { "$binary" : "AN6GmE7Thi+Sd/dpLRjIilgsV/4AAAg=", "$type" : "00" },
"auditVersion" : "1.0",
"currentTime" : NumberLong(1479301118381),
"data" : {
"deviceDesign" : "bullhead",
"loginType" : "GOOGLE",
"source" : "SDKLoader",
"systemUptimeMillis" : 137652880.0,
"simCountryIso" : "il",
"networkOperatorName" : "Cellcom",
"hasPhonePermission" : true,
"deviceIdentifier" : "353627074839559",
"sdkVersion" : "0.7.939.2016-11-14.masterDev",
"brand" : "google",
"osVersion" : "7.0",
"osVersionIncremental" : "3239497",
"deviceModel" : "Nexus 5X",
"deviceSDKVersion" : 24.0,
"manufacturer" : "LGE",
"sdkShortBuildDate" : "2016-11-14",
"sdkFullBuildDate" : "Mon Nov 14 22:16:40 IST 2016",
"product" : "bullhead"
},
"timezone" : "Asia/Jerusalem",
"collectionAlias" : "DEVICE_DATA",
"shortDate" : 17121,
"userId" : "00DE86984ED3862F9277F7692D18C88A#1927cc81cfcf7a467e9d4f4ac7a1534b"}
this is an example of how one key locks like.
The below query should give you distinct count of userId for a deviceModel. I meant if a same userId present for a deviceModel multiple items, it will be counted only once.
db.collection.aggregate([ {"$group" : {_id:"$data.deviceModel", userIds:{$addToSet: "$userId"}}
},
{
$unwind:"$userIds"
},
{
$group: { _id: "$_id", userIdCount: { $sum:1} }
}])
Unwind:-
Deconstructs an array field from the input documents to output a
document for each element.
In the above solution, it deconstructs the userId array formed on the first pipeline.
addToSet:-
Returns an array of all unique values that results from applying an
expression to each document in a group of documents that share the
same group by key.
This function ensures that only unique values are added to an array. In the above case, the userId is added to an array in the first pipeline.
I am implementing a ranking system. I have a collection with elements like this:
{"_id" : 1, "count" : 32}
{"_id" : 2, "count" : 12}
{"_id" : 3, "count" : 34}
{"_id" : 4, "count" : 9}
{"_id" : 5, "count" : 77}
{"_id" : 6, "count" : 20}
I want to write a query that return an element which has {"id" : 1} and 2 other neighbor elements (after sorting by count). Totally 3 elements returned.
Ex:
After sorting:
9 12 20 32 34 77
The query should return 20 32 34.
You will never get this in a single query operation, but it can be obtained with "three" queries. The first to obtain the value for "count" from the desired element, and the subsequent ones to find the "preceding" and "following" values.
var result = [];
var obj = db.collection.findOne({ "_id": 1 }); // returns object as selected
result.push(obj);
// Preceding
result.unshift(db.collection.findOne({
"$query": { "count": { "$lt": obj.count } },
"$orderby": { "count": -1 }
}));
// Following
result.push(db.collection.findOne({
"$query": { "count": { "$gt": obj.count } },
"$orderby": { "count": 1 }
}));
Asking to do this in a "single query" is essentially asking for a "join", which is something that MongoDB essentially does not do. It is a "Set Intersection" of the discrete results, and that in SQL is basically a "join" operation.
I'm creating an index file in JSON, which I'm using as a sort-of-database index for a javascript application I'm working on.
My index will look like this:
{
"_id": "acomplex_indices.json",
"indexAB": {
"title": {
"Shawshank Redemption": [
"0"
],
"Godfather": [
"1"
],
"Godfather 2": [
"2"
],
"Pulp Fiction": [
"3"
],
"The Good, The Bad and The Ugly": [
"4"
],
"12 Angry Men": [
"5"
],
"The Dark Knight": [
"6"
],
"Schindlers List": [
"7"
],
"Lord of the Rings - Return of the King": [
"8"
],
"Fight Club": [
"9"
],
"Star Wars Episode V": [
"10"
],
"Lord Of the Rings - Fellowship of the Ring": [
"11"
],
"One flew over the Cuckoo's Nest": [
"12"
],
"Inception": [
"13"
],
"Godfellas": [
"14"
]
},
"year": {
"1994": [
"0",
"3"
],
"1972": [
"1"
],
"1974": [
"2"
],
"1966": [
"4"
],
"1957": [
"5"
],
"2008": [
"6"
],
"1993": [
"7"
],
"2003": [
"8"
],
"1999": [
"9"
],
"1980": [
"10"
],
"2001": [
"11"
],
"1975": [
"12"
],
"2010": [
"13"
],
"1990": [
"14"
]
}
}
}
So for every keyword (like Pulp Fiction), I'm storing the matching document-id(s).
My problem is with integers/numbers/non-string data, like the release year in the above example. This is stored as a string, while I had hoped it would be stored as a number.
I'm creating the index entries like this:
// indices = the current index file
// doc = the document to update the index with
// priv.indices = all indices defined for this application instance
// priv.indices.fields = index fields e.g. "year", "director", "title"
// priv.indices.name = name of this index
priv.updateIndices = function (indices, doc) {
var i, j, index, value, label, key, l = priv.indices.length;
// loop all indices to add document
for (i = 0; i < l; i += 1) {
index = {};
index.reference = priv.indices[i];
index.reference_size = index.reference.fields.length;
index.current = indices[index.reference.name];
for (j = 0; j < index.reference_size; j += 1) {
label = index.reference.fields[j]; // like "year"
value = doc[label]; // like 1985
// if document has a label field (e.g. doc.year = 1985)
if (value !== undefined) {
// check if the index file already contains an entry for 1985
index.current_size = priv.getObjectSize(index.current[label]);
if (index.current_size > 0) {
// check if the document id is already in the index
// in case the data is updated (e.g. change 1982 to 1985)
key = priv.searchIndexByValue(
index.current[label],
doc._id,
"key"
);
if (!!key) {
delete index.current[label][key];
}
}
// create a new array if 1985 is not in the index yet
if (index.current[label][value] === undefined) {
index.current[label][value] = [];
}
// add the document id to an existing entry
index.current[label][value].push(doc._id);
}
}
}
return indices;
};
This works fine, except that fields I want to store as non-strings (integers, numbers or datetime), like the year in the above example end up as strings in my index.
Question:
Is it at all possible to store "non-string" types in a JSON document? If so, can I also store the key of a key/value pair as a "non-string" element.
If not, would I have to add a parameter to my index definitions declaring the type of each key in order to modify the key-string when I run into it or is there a better way to do it?
Thanks!
Is it at all possible to store "non-string" types in a JSON document?
Yes. The value of a property can be a string, number, boolean, object, array or null (undefined is a notable exception - it's a native JavaScript type but it's not a valid JSON value).
Can I also store the key of a key/value pair as a "non-string" element?
No. The key name must always be a string. However, that doesn't mean you can't parse that string into some other JavaScript type. For example, if you have a string but need a number, you can use the parseInt function, or the unary + operator.
See the JSON grammar for more detail.
no you can't, in JSON keys are strings.
the best you can do is storing string representations of those keys, wether integer or objects(more complicated, you have to build a serialization function).
If you want to use only consecutive integers keys starting from 0, then you can use arrays.
According to the json spec, you can have a number anywhere you could have a value. So the key of an object must be a string, but the value can be a number. Also any of the values in an array can be a number.
The spec is beside the point though; I believe the issue is this line:
index.current[label][value].push(doc._id);
When you read doc._id, that is a string. If you want to store it in the JSON as a number, you need to cast it:
index.current[label][value].push(parseInt(doc._id, 10));
Also note that having just numbers as IDs is not valid HTML.