Sort nested array by properties [duplicate] - javascript

This question already has answers here:
Sort array of objects by string property value
(57 answers)
Closed 8 years ago.
I have this array and I was wondering if I could sort it with the properties comments.count and likes.count separately.
For example I could just have a function to call using likes.count parameter or comments.count parameter.
{
"attribution": null,
"tags": [
],
"type": "",
"location": null,
"comments": {
"count": 2,
"data": [
{
"created_time": "1385670850",
"text": "Holy shit",
"from": {
"username": "someone",
"profile_picture": "http://url.com/profiles/profile_191120775_75sq_1365830292.jpg",
"id": "191120775"
},
"id": "599372997379438683"
},
{
"created_time": "1385680581",
"text": "",
"from": {
"username": "someone",
"profile_picture": "http://url.com/profiles/profile_1523167_75sq_1389544912.jpg",
"id": "1523167"
},
"id": "599454624038205610"
}
]
},
"likes": {
"count": 6,
"data": [
{
"username": "someone",
"profile_picture": "http://url.com/profiles/profile_2169761_75sq_1389075971.jpg",
"id": "2169761"
},
{
"username": "rashmityagi",
"profile_picture": "http://url.com/profiles/profile_393770264_75sq_1388911033.jpg",
"id": "393770264"
},
{
"username": "tylerferweda",
"profile_picture": "http://url.com/profiles/profile_191120775_75sq_1365830292.jpg",
"id": "191120775"
},
{
"username": "cbolts",
"profile_picture": "http://url.com/profiles/profile_1523167_75sq_1389544912.jpg",
"id": "1523167"
}
]
}
},
{
"attribution": null,
"tags": [
],
"type": "",
"location": null,
"comments": {
"count": 10,
"data": [
{
"created_time": "1385670850",
"text": "Holy shit",
"from": {
"username": "someone",
"profile_picture": "http://url.com/profiles/profile_191120775_75sq_1365830292.jpg",
"id": "191120775"
},
"id": "599372997379438683"
},
{
"created_time": "1385680581",
"text": "",
"from": {
"username": "someone",
"profile_picture": "http://url.com/profiles/profile_1523167_75sq_1389544912.jpg",
"id": "1523167"
},
"id": "599454624038205610"
}
]
},
"likes": {
"count": 20,
"data": [
{
"username": "someone",
"profile_picture": "http://url.com/profiles/profile_2169761_75sq_1389075971.jpg",
"id": "2169761"
},
{
"username": "rashmityagi",
"profile_picture": "http://url.com/profiles/profile_393770264_75sq_1388911033.jpg",
"id": "393770264"
},
{
"username": "tylerferweda",
"profile_picture": "http://url.com/profiles/profile_191120775_75sq_1365830292.jpg",
"id": "191120775"
},
{
"username": "cbolts",
"profile_picture": "http://url.com/profiles/profile_1523167_75sq_1389544912.jpg",
"id": "1523167"
}
]
}
},

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
json_array.sort(function(a, b) {
if(a.comments.count < b.comments.count) {
return -1;
}
if(a.comments.count > b.comments.count) {
return 1;
}
return 0;
});
You can also modify it for likes.count

Underscore.js provides great utility functions for working with arrays and objects. For your case you could use _.sortBy(...) See http://underscorejs.org/#sortBy for more details. For simple object properties it is enough to specify the object property name als last parameter.

Related

Adding attributes to existing json payload using javascript

I am getting json response as below. I want to add "**
schemas":[
"urn:ietf:params:scim:schemas:core:2.0:User", "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
],
"id":"xyz",
**
to each resource how to do this using javascript. Can anyone help.
{
"Resources": [
{
"emails": {
"type": "bobsmith01#company.com",
"value": "Personal"
},
"name": {
"familyName": "Bob-update3",
"givenName": "Smith"
},
"detail": "SUCCESS",
"userName": "bobsmith01#company.com",
"status": "200"
},
{
"emails": {
"type": "samgomes#company.com",
"value": "Personal"
},
"name": {
"familyName": "gomes",
"givenName": "sam"
},
"detail": "SUCCESS",
"userName": "samgomes#company.com",
"status": "200"
}
]
}
Required output is as below.
{
"Resources": [
{
"schemas":[
"urn:ietf:params:scim:schemas:core:2.0:User",
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
],
"id":"xyz",
"emails": {
"type": "bobsmith01#company.com",
"value": "Personal"
},
"name": {
"familyName": "Bob-update3",
"givenName": "Smith"
},
"detail": "SUCCESS",
"userName": "bobsmith01#company.com",
"status": "200"
}
{
"schemas":[
"urn:ietf:params:scim:schemas:core:2.0:User",
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
],
"id":"abc",
"emails": {
"type": "samgomes#company.com",
"value": "Personal"
},
"name": {
"familyName": "gomes",
"givenName": "sam"
},
"detail": "SUCCESS",
"userName": "samgomes#company.com",
"status": "200"
}
]
}
You can use ES6 JS spread operator (...) and Array.map to achieve this:
const orgObject = {
"Resources": [{
"emails": {
"type": "bobsmith01#company.com",
"value": "Personal"
},
"name": {
"familyName": "Bob-update3",
"givenName": "Smith"
},
"detail": "SUCCESS",
"userName": "bobsmith01#company.com",
"status": "200"
},
{
"emails": {
"type": "samgomes#company.com",
"value": "Personal"
},
"name": {
"familyName": "gomes",
"givenName": "sam"
},
"detail": "SUCCESS",
"userName": "samgomes#company.com",
"status": "200"
}
]
}
const copiedObject = {...orgObject}; // Copy object to avoid mutation preferably use lodash.cloneDeep
// loop through the object.Resources using map
copiedObject.Resources = copiedObject.Resources.map(res => {
return {
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User",
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
],
"id": "xyz",
...res // Use spread operator to copy the existing object properties from Resources
}
});
console.log(copiedObject)
.as-console-wrapper{
top:0;
max-height:100% !important;
}

How to elegantly get a particular value from highly nested json object in JavaScript? [duplicate]

This question already has answers here:
JavaScript property access: dot notation vs. brackets?
(17 answers)
Closed 8 months ago.
This is my json object by name data
{
"data": {
"id": "---------",
"type": "licenses",
"attributes": {
"name": "Floating Point Lic",
"key": "-----------",
"expiry": "2022-07-30T19:11:30.738Z",
"status": "ACTIVE",
"uses": 0,
"suspended": false,
"scheme": "ED25519_SIGN",
"encrypted": false,
"strict": true,
"floating": true,
"protected": true,
"maxMachines": 10,
"maxProcesses": null,
"maxCores": null,
"maxUses": null,
"requireHeartbeat": false,
"requireCheckIn": false,
"lastValidated": "2022-07-07T08:33:58.195Z",
"lastCheckIn": null,
"nextCheckIn": null,
"metadata": {
"role": "sde"
},
"created": "2022-06-30T19:11:30.736Z",
"updated": "2022-07-07T08:33:58.199Z"
},
"relationships": {
"account": {
"links": {
"related": "------------"
},
"data": {
"type": "accounts",
"id": "------------"
}
},
"product": {
"links": {
"related": "------------------"
},
"data": {
"type": "products",
"id": "This I need"
}
},
"policy": {
"links": {
"related": "---------"
},
"data": {
"type": "policies",
"id": "---------------"
}
},
"group": {
"links": {
"related": "------------"
},
"data": null
},
"user": {
"links": {
"related": "---------------"
},
"data": null
},
"machines": {
"links": {
"related": "-------------------"
},
"meta": {
"cores": 0,
"count": 0
}
},
"tokens": {
"links": {
"related": "----------------"
}
},
"entitlements": {
"links": {
"related": "------------------"
}
}
},
"links": {
"self": "-------------"
}
},
"meta": {
"ts": "2022-07-07T08:33:58.204Z",
"valid": false,
"detail": "must have at least 1 associated machine",
"constant": "NO_MACHINES"
}
}
Their is data then their is relationships then product then data then id which I want
I am currently getting it by writing
r['data']['data']['relationships']['product']['data']['id']
r here is this object but this does not looks elegant at all. Is their any way to fetch this in a better manner?
Use dots instead of brackets:
const wantedId = r.data.relationships.product.data.id;
Brackets are only useful if you're using dynamic references to properties.

More efficient way to remove from an object attributes present in a group of objects

I'm manipulating some javascript objects and I want to know if is there a more efficient and easy way to process my data.
I already do that, but I'm a beginner in js.
I have four objects with this structure: basically there is an array of blocks and any object has a different number of blocks. In every block, in the features attribute, I have another array with some features.
Then I have another object, and I have to remove from this object (I call it structure) blocks and features that are not present in my four initial object.
This is a sample product object
[
{
"ID": 16293,
"SortNo": "20",
"FeatureGroup": {
"ID": "148",
"Name": {
"Value": "Design",
"Language": "IT"
}
},
"Features": [
{
"Localized": 0,
"ID": "155744521",
"Type": "dropdown",
"Value": "Round",
"CategoryFeatureId": "85327",
"CategoryFeatureGroupID": "16293",
"SortNo": "155",
"PresentationValue": "Rotondo",
"RawValue": "Round",
"LocalValue": [],
"Description": "The external form",
"Mandatory": "1",
"Searchable": "0",
"Feature": {
"ID": "9397",
"Sign": "",
"Measure": {
"ID": "29",
"Sign": "",
"Signs": {
"ID": "",
"_": "",
"Language": "IT"
}
},
"Name": {
"Value": "Forma",
"Language": "IT"
}
}
},
{
"Localized": 0,
"ID": "155655523",
"Type": "multi_dropdown",
"Value": "White",
"CategoryFeatureId": "85298",
"CategoryFeatureGroupID": "16293",
"SortNo": "90",
"PresentationValue": "Bianco",
"RawValue": "White",
"LocalValue": [],
"Description": "The colour of the housing",
"Mandatory": "1",
"Searchable": "1",
"Feature": {
"ID": "10059",
"Sign": "",
"Measure": {
"ID": "29",
"Sign": "",
"Signs": {
"ID": "",
"_": "",
"Language": "IT"
}
},
"Name": {
"Value": "Colore struttura",
"Language": "IT"
}
}
},
{
"Localized": 0,
"ID": "155655525",
"Type": "multi_dropdown",
"Value": "White",
"CategoryFeatureId": "85301",
"CategoryFeatureGroupID": "16293",
"SortNo": "80",
"PresentationValue": "Bianco",
"RawValue": "White",
"LocalValue": [],
"Description": "The colour of the band",
"Mandatory": "1",
"Searchable": "1",
"Feature": {
"ID": "11025",
"Sign": "",
"Measure": {
"ID": "29",
"Sign": "",
"Signs": {
"ID": "",
"_": "",
"Language": "IT"
}
},
"Name": {
"Value": "Colore cinturino",
"Language": "IT"
}
}
},
{
"Localized": 0,
"ID": "219617494",
"Type": "y_n",
"Value": "Y",
"CategoryFeatureId": "168947",
"CategoryFeatureGroupID": "16293",
"SortNo": "-6",
"PresentationValue": "Sì",
"RawValue": "Y",
"LocalValue": [],
"Description": "The product is protected from water",
"Mandatory": "0",
"Searchable": "0",
"Feature": {
"ID": "7509",
"Sign": "",
"Measure": {
"ID": "26",
"Sign": "",
"Signs": {
"ID": "",
"_": "",
"Language": "IT"
}
},
"Name": {
"Value": "Resistente all'acqua",
"Language": "IT"
}
}
}
]
},
{
"ID": 34567,
"SortNo": "20",
"FeatureGroup": {
"ID": "184",
"Name": {
"Value": "Prestazione",
"Language": "IT"
}
},
"Features": [
{
"Localized": 0,
"ID": "155744528",
"Type": "y_n",
"Value": "N",
"CategoryFeatureId": "94697",
"CategoryFeatureGroupID": "34567",
"SortNo": "800",
"PresentationValue": "No",
"RawValue": "N",
"LocalValue": [],
"Description": "La Frequenza modulare radio produce la miglior recezione di qualsiasi canale radio. Quando viene usato un auricolare, produce un effetto di suono da stereo r",
"Mandatory": "1",
"Searchable": "0",
"Feature": {
"ID": "2172",
"Sign": "",
"Measure": {
"ID": "26",
"Sign": "",
"Signs": {
"ID": "",
"_": "",
"Language": "IT"
}
},
"Name": {
"Value": "Radio FM",
"Language": "IT"
}
}
},
{
"Localized": 0,
"ID": "155744530",
"Type": "multi_dropdown",
"Value": "Not supported",
"CategoryFeatureId": "85357",
"CategoryFeatureGroupID": "34567",
"SortNo": "500",
"PresentationValue": "Non supportato",
"RawValue": "Not supported",
"LocalValue": [],
"Description": "Types of memory cards which can be used with this product.",
"Mandatory": "1",
"Searchable": "0",
"Feature": {
"ID": "730",
"Sign": "",
"Measure": {
"ID": "29",
"Sign": "",
"Signs": {
"ID": "",
"_": "",
"Language": "IT"
}
},
"Name": {
"Value": "Tipi schede di memoria",
"Language": "IT"
}
}
}
]
}
]
Here i loop my initial objects (this.compare_products) to extract, in two arrays (featureGroupIds - featureIds) the ID of my block and the CategoryFeatureId
let featureGroupIds = []
let featureIds = []
this.compare_products.forEach((object) => {
featureGroupIds = featureGroupIds.concat(FeaturesGroups.map(o => o.ID))
featureIds = featureIds.concat(FeaturesGroups.map(o => o.Features.map(o => o. CategoryFeatureId))).flat(2)
})
The two arrays, featureGroupIds and featureIds are now filled with every block ID and every CategoryFeatureId present in my four object.
Now I have to filter the object I call "structure" to remove the block and the features with an ID that is not present in my arrays.
This is my structure, and as you can see is similar.
[
{
"name": "Display",
"data": {
"id": 34566,
"category_id": 2647
},
"features": [
{
"name": "Tipo di display",
"data": {
"id": 85325,
"category_id": 2647,
"feature_id": 9104,
"category_feature_group_id": 34566,
"order": 10100140
}
},
{
"name": "Touch screen",
"data": {
"id": 85331,
"category_id": 2647,
"feature_id": 4963,
"category_feature_group_id": 34566,
"order": 10100129
}
},
{
"name": "Dimensioni schermo",
"data": {
"id": 158002,
"category_id": 2647,
"feature_id": 3544,
"category_feature_group_id": 34566,
"order": 100149
}
},
{
"name": "à di Pixel",
"data": {
"id": 85347,
"category_id": 2647,
"feature_id": 13246,
"category_feature_group_id": 34566,
"order": 100147
}
},
{
"name": "Tipo di vetro",
"data": {
"id": 94704,
"category_id": 2647,
"feature_id": 7610,
"category_feature_group_id": 34566,
"order": 100050
}
}
]
},
{
"name": "Altre caratteristiche",
"data": {
"id": 34569,
"category_id": 2647,
"feature_group_id": 146,
"name": null,
"order": 0
},
"features": [
{
"name": "inside",
"data": {
"id": 110410,
"category_id": 2647,
"feature_id": 18688,
"category_feature_group_id": 34569,
"order": 100000
}
}
]
}
]
Here is my function
structure = structure.filter(featureGroup => this.featureGroupIds.includes(featureGroup.data.id));
structure.map((object) => {
object.features.filter(feature => this.featureIds.includes(feature.data.feature_id))
})
this.featureIds and this.featureGroupIds are the array with the group IDS and with the feature IDS.
Is there a more efficient way to do this?

Paasing an object into an array of arrays

Have an object that needs to be pass inside the array of source using javascript,throwing an error spec is undefined when using push function. will push function work for this scenario
var a = [
"name": "ben",
"type": "male",
"appType": "human",
"spec": {
"view": "instanceview",
"sink": {
"source": [{
"data": {
"path": "google/path",
"name": "test",
"Id": "11234",
},
"ref": "www.xyz.com",
"id": "isdfjsbfjsfb",
"resourceType": "app"
}
],
},
},
}]
var b = {
"data": {
"path": "google/path",
"name": "goldengate",
"Id": "11234vndslknvlsmnv",
},
"ref": "www.xyz.com",
"id": "6452367e5375",
"resourceType": "app"
}
a.spec.sink.source.push(b);
would expect b to be pushed to source
An array with string keys is not a valid structure, you need to convert a to an object
var a = { // <-- here
"name": "ben",
"type": "male",
"appType": "human",
"spec": {
"view": "instanceview",
"sink": {
"source": [
{
"data": {
"path": "google/path",
"name": "test",
"Id": "11234",
},
"ref": "www.xyz.com",
"id": "isdfjsbfjsfb",
"resourceType": "app"
}
],
},
},
} // <-- here

JSON Object Transformation into specific Javascript Array or JSON Object

So I have this JSON Object. Let's call it var dataFetched
var dataFetched = {
"status": "ok",
"count": 4,
"count_total": 4,
"pages": 1,
"posts": [
{
"id": 57,
"type": "keyword",
"slug": "crime-scene-investigation-csi",
"url": "http://keyjargon.com/keyword/crime-scene-investigation-csi/",
"status": "publish",
"title": "Crime Scene Investigation (CSI)",
"title_plain": "Crime Scene Investigation (CSI)",
"content": "",
"excerpt": "",
"date": "2015-11-07 05:01:51",
"modified": "2015-11-07 05:01:51",
"categories": [
{
"id": 8,
"slug": "law",
"title": "Law",
"description": "",
"parent": 0,
"post_count": 1
}
],
"tags": [
],
"author": {
"id": 1,
"slug": "admin",
"name": "admin",
"first_name": "",
"last_name": "",
"nickname": "admin",
"url": "",
"description": ""
},
"comments": [
],
"attachments": [
],
"comment_count": 0,
"comment_status": "closed",
"custom_fields": {
}
},
{
"id": 50,
"type": "keyword",
"slug": "fx",
"url": "http://keyjargon.com/keyword/fx/",
"status": "publish",
"title": "FX",
"title_plain": "FX",
"content": "",
"excerpt": "",
"date": "2015-11-05 10:07:17",
"modified": "2015-11-05 10:22:10",
"categories": [
{
"id": 3,
"slug": "business",
"title": "Business",
"description": "",
"parent": 0,
"post_count": 2
}
],
"tags": [
],
"author": {
"id": 1,
"slug": "admin",
"name": "admin",
"first_name": "",
"last_name": "",
"nickname": "admin",
"url": "",
"description": ""
},
"comments": [
],
"attachments": [
],
"comment_count": 0,
"comment_status": "closed",
"custom_fields": {
}
},
{
"id": 48,
"type": "keyword",
"slug": "common-core",
"url": "http://keyjargon.com/keyword/common-core/",
"status": "publish",
"title": "Common CORE",
"title_plain": "Common CORE",
"content": "",
"excerpt": "",
"date": "2015-11-05 10:06:40",
"modified": "2015-11-07 04:58:06",
"categories": [
{
"id": 2,
"slug": "technology",
"title": "Technology",
"description": "",
"parent": 0,
"post_count": 3
}
],
"tags": [
],
"author": {
"id": 1,
"slug": "admin",
"name": "admin",
"first_name": "",
"last_name": "",
"nickname": "admin",
"url": "",
"description": ""
},
"comments": [
],
"attachments": [
],
"comment_count": 0,
"comment_status": "closed",
"custom_fields": {
}
},
{
"id": 46,
"type": "keyword",
"slug": "api",
"url": "http://keyjargon.com/keyword/api/",
"status": "publish",
"title": "API",
"title_plain": "API",
"content": "",
"excerpt": "",
"date": "2015-11-05 10:06:19",
"modified": "2015-11-05 10:21:47",
"categories": [
{
"id": 2,
"slug": "technology",
"title": "Technology",
"description": "",
"parent": 0,
"post_count": 3
}
],
"tags": [
],
"author": {
"id": 1,
"slug": "admin",
"name": "admin",
"first_name": "",
"last_name": "",
"nickname": "admin",
"url": "",
"description": ""
},
"comments": [
],
"attachments": [
],
"comment_count": 0,
"comment_status": "closed",
"custom_fields": {
}
}
]
}
I want to rearrange this result to link the Category title :
dataFetched.posts[i].categories[0].title
to the Post title :
dataFetched.post[i].title
so that each category displays all the posts titles related to it. I want my object (whether multi-demmensional array or another object) to be able to retrieve all the Posts titles related to the category.
Maybe something like this :
[Category1: {Post_titleA, PostTitleB, PostTitleC}, Category2: {PostTileF, PostTileX}, etc ] where each category can retrieve all its posts.( The format does not matter as long the Object with Category title X can retrieve all posts titles that belong to it ).
How do I do this in Javascript ? The result variable is not static but its format is the same as the one posted here.
This is what I tried so far.
// Function to sort unique values of an array
function sort_unique(arr) {
arr = arr.sort(function (a, b) { return a*1 - b*1; });
var ret = [arr[0]];
for (var i = 1; i < arr.length; i++) { // start loop at 1 as element 0 can never be a duplicate
if (arr[i-1] !== arr[i]) {
ret.push(arr[i]);
}
}
return ret;
}
//Define two arrays to be used for categories and Keywords
var keywords = [];
var industries = [];
//Fill up the categories(Industries) array and the keywords one
for ( var i = 0, iLen = dataFetched.count; i < iLen; i++) {
keywords[i] = dataFetched.posts[i].title;
industries[i] = dataFetched.posts[i].categories[0].title;
}
// Sort and eliminate duplication of category and keyword names
keywords = sort_unique(keywords);
industries = sort_unique(industries);
// Now time for trouble: Define a multi-dimmensional array that links each category/industry to its keywords **This is where I AM STUCK**
ind = new Array;
for(i=0; i<industries.length;i++){
ind[i] = new Array;
}
for(i=0;i<dataFetched.count;i++){
ind[i][0]= dataFetched.posts[i].categories[0].title;
for(j=0;j<dataFetched.count;j++){
var count = ind[i].length;
if(ind[i][0] == dataFetched.posts[j].categories[0].title){
ind[i][count] = dataFetched.posts[j].title;
}
}
}
It is possible to create object with categories. As a result all entries can be accessed by category name and you do not need to sort them to have unique titles:
var posts = dataFetched.posts;
var cat = {};
posts.forEach(
function(p) {
p.categories.forEach(
function(c) {
if (!cat[c.title])
cat[c.title] = [];
cat[c.title].push(p.title);
});
});
console.log(cat);
Output for your example:
Object {Law: Array[1], Business: Array[1], Technology: Array[2]}
Each category title is a key in this object and the arrays of posts are values of those keys.
The output example you showed is wrong, in JS there's no object like
[Category1: {Post_titleA, PostTitleB, PostTitleC}, Category2: {PostTileF, PostTileX}, etc ]
The most similar thing you can get is a JSON object like this:
{
"Category1" : ["Post_titleA", "PostTitleB", "PostTitleC"],
"Category2" : ["PostTileF", "PostTileX"],
//etc..
}
In order to achieve this, you can use the following function:
function getTitlesByCategory (json) {
var result = {}
json.posts.map(function (post) {
post.categories.map(function (category) {
result[category.title] = result[category.title] || [];
result[category.title].push(post.title);
});
});
return result;
}

Categories