Related
I have this json I need to format it in Typescript or java script. what would be better way to do.
var data = {
"value 1" : [
{
type : String,
Dicription : "abc"
},
{
type : int,
Dicription : "xyz"
},
{
type : String,
Dicription : "pqr"
},
]
"value 2" : [
{
type : String,
Dicription : "abc"
}
]
"value 3" : [
{
type : String,
Dicription : "abc"
},
{
type : int,
Dicription : "xyz"
}
}
Need Output like this
{
{
value : value1,
type : String,
Description : "abc"
},
{
value : value1,
type : int,
Dicription : "xyz"
},
{
value : value1,
type : String,
Dicription : "pqr"
},
{
value : value2,
type : String,
Description : "abc"
},
{
value : value3,
type : String,
Description : "abc"
},
{ value : value3,
type : int,
Description : "xyz"
}
}
I tried
var new = [];
Var values = Object.keys(data)
values.ForEach(Function(value){
new.push({
'value' : value })
});
and iterate it, but could not get desired output. I tried to flatten this but I got objects like {value : value , { type: String ,Description : abc}}
What should I do to solve it
Convert the object to an an array using Object.entries(), and then flat map the entries to an array of objects:
const result = Object.entries(data) // get the entries of the object
.flatMap(([value, arr]) => // map and flatten the sub-arrays
arr.map(o => ({ // map each sub-array and combine with the value
value,
...o
}))
)
I get the keys and values separately and iterate though first object and create another object and push values in it.
So my solution for the problem is
var keys = Object.keys(data);
var values = Object.values(data);
var length = Object.values(data).length;
keys.ForEach(function (key, index){
values.ForEach(function (obj, i) {
if(index == i){
var innerValue = Object.values(obj);
for(i=0 ; i<=innerValue.length; i++)
{
new.push({
'value: key,
'type': innerValue[i].type,
'Description': innerValue[i].abc,
});
}
}
});
});```
I have following object array:
var arr = [
{
id : "a1",
guid : "sdfsfd",
...
value : "abc",
status: "active"
},
{
id : "a2",
guid : "sdfsfd",
...
value : "def",
status: "inactive"
},
{
id : "a2",
guid : "sdfsfd",
...
value : "def"
},
...
]
How to set "status" property of each object to "active". So the resulting array will be:
var arr = [
{
id : "a1",
guid : "sdfsfd",
...
value : "abc",
status: "active"
},
{
id : "a2",
guid : "sdfsfd",
...
value : "def",
status: "active"
},
{
id : "a2",
guid : "sdfsfd",
...
value : "def",
status: "active"
},
...
]
Additionally this should create the property "active" if doesn't exists.
I can do this using for loops. But I'm pretty much sure lodash can do this in one line like:
arr = _.set_property(arr, "status", "active");
You don't need lodash for this.
The first object is missing your status property and it will be added.
SHOWING THREE WAYS HOW YOU CAN DO IT
IMMUTABLE VERSION (We create a new array using map)
const arrImmutableVersion = arr.map(e => ({...e, status: "active"}));
MUTABLE VERSIONS (We change the original array)
arr.forEach((el)=>{el.status = "active";})
or
arr.forEach(function(el){el.status = "active";})
var arr = [
{
id : "a1",
guid : "sdfsfd",
value : "abc"
},
{
id : "a2",
guid : "sdfsfd",
value : "def",
status: "inactive"
},
{
id : "a2",
guid : "sdfsfd",
value : "def",
status: "active"
}
];
// SHOWING THREE WAYS HOW YOU CAN DO IT
// MUTABLE VERSIONS - We change the original array
arr.forEach((el)=>{el.status = "active";}) // ES6
// or
arr.forEach(function(el){el.status = "active";})
//or
// IMMUTABLE VERSION - We create a new array using `map`
const arrImmutableVersion = arr.map(e => ({...e, status: "active"})); // ES6
//--------------------------------------------------------------
// RESULTS:
console.log("logging results of object 'arr'");
console.log(arr);
console.log("---------------------------------------------------------");
console.log("logging results of object 'arrImmutableVersion'");
console.log(arrImmutableVersion);
Indeed, you don't need Lodash, but the question is tagged Lodash, and using Lodash offers some useful defenses that reduces the risk of errors. This solution utilizes _.forEach and _.set
// _.forEach won't throw errors if arr is not an array...
_.forEach(arr, function (obj) {
// _.set won't throw errors if obj is not an object. With more complex objects, if a portion of the path doesn't exist, _.set creates it
_.set(obj, 'status', 'active');
});
If you wanted to make it abstract, you could build a Lodash mixin:
_.mixin({
setProperty: function(arr, key, val) {
_.forEach(arr, function (obj) {
_.set(obj, path, val);
});
}
});
Then, you could use it exactly as you described:
_.setProperty( arr, 'status', 'active' );
A way simpler and and cleaner way !
If you want to use func programming in a proper manner
myArray = myArray.map(arrayElem => {
arrayElem.property = newValue
return arrayElem
})
I'm trying to sort a JSON into multiple arrays based on type, my current json is:
// current json file:
{
"res": [
{
"type" : "stream",
"price" : "3.99",
"id" : "13nee"
},
{
"type" : "stream",
"price" : "2.99",
"id" : "8ejwj"
},
{
"type" : "buy",
"price" : "3.99".
"id" : "9akwk"
},
...
]
}
I'm looking to sort it into multiple arrays by type like below:
var sorted = {
"stream" : [
{
"price" : "2.99",
"id" : "8ejwj"
},
{
"price" : ".99",
"id" : "13nee"
},
... // other objects with type: "stream"
],
"buy" : [
{
"price" : "3.99".
"id" : "9akwk"
},
... // other objects with type: "buy"
]
}
I've tried it, but the only solution I can think of is by cases - run if loop, if case matches type, then push object to array. Is there a more elegant solution?
var items = {};
var i = 0;
for(i; i < res.length; i += 1){
var resItem = res[i];
if(items.hasOwnProperty(resItem.type)){
items[resItem.type].push({price:resItem.price, id:resItem.id});
} else {
items[resItem.type] = [{price:resItem.price, id:resItem.id}];
}
}
The properties on JavaScript objects are hashed, so you can dynamically match and generate new objects like above. If you want to apply a well ordering sort, you'll need to apply it to the arrays of the newly generated items object.
Step 1 :
Convert the JSON to a jquery object :
var x = jQuery.parseJSON( jsonString );
Step 2:
Use underscore library's _.groupBy to group :
_.groupBy(x,'type');
There might be some adjustment you need to do for x being array or object.
Edit :
You don't need step1. Just do :
sorted = _.groupBy(json.res,'type');
You could do something like this with ECMA5. This performs, generically, the sort and reduce that you have indicated in your question, so you can add more fields to your data without having to change the routine. It also leaves your original data intact.
Javascript
var original = {
'res': [{
'type': 'stream',
'price': '3.99',
'id': '13nee'
}, {
'type': 'stream',
'price': '2.99',
'id': '8ejwj'
}, {
'type': 'buy',
'price': '3.99',
'id': '9akwk'
}]
},
sorted = {};
original.res.slice().sort(function (a, b) {
a = +(a.price);
b = +(b.price);
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
}).reduce(function (acc, element) {
if (!acc[element.type]) {
acc[element.type] = [];
}
acc[element.type].push(Object.keys(element).filter(function (name) {
return name !== 'type';
}).reduce(function (prev, name) {
prev[name] = element[name];
return prev;
}, {}));
return acc;
}, sorted);
console.log(JSON.stringify(sorted));
Output
{
"stream": [{
"price": "2.99",
"id": "8ejwj"
}, {
"price": "3.99",
"id": "13nee"
}],
"buy": [{
"price": "3.99",
"id": "9akwk"
}]
}
On jsFiddle
I have several objects like this:
I want to move type and value one step up so they will be next to field, and then delete data.
It looks like this when departments is converted to JSON:
[
{"field" : "DEPARTMAN_NO",
"data" : { "type":"numeric" , "comparison":"eq" , "value":11 }
},
{"field" : "DEPARTMAN_ADI",
"data" : { "type":"string" , "value":"bir" }
}
]
I have tried:
departments = grid.filters.getFilterData();
i = {};
for(var i in department) {
department = i.data;
delete.department.data;
};
but it dosen't work.
1) First, loop departments, each item we call it department;
2) You want to move department.data's properties to department, From another angle, you can move department's properties to department.data and return department.data, code like:
var departments = [{
"field": "DEPARTMAN_NO",
"data": {
"type": "numeric",
"comparison": "eq",
"value": 11
}
}, {
"field": "DEPARTMAN_ADI",
"data": {
"type": "string",
"value": "bir"
}
}],
department;
for (var i = 0, len = departments.length; i < len; i++) {
department = departments[i]; // department
for (var key in department) {
if (key !== 'data' && department.data) {
department.data[key] = department[key];
}
}
departments[i] = department.data || department; // if no department.data, no change
}
console.log(departments);
result:
view the full demo http://jsfiddle.net/KVYE5/
I wrote a little npm package that does what you're asking for: moving a property up a level in an object.
You can get it here: https://www.npmjs.com/package/move-property-up-a-level
Usage
var movePropertyUpALevel = require('movePropertyUpALevel');
var fakeObj = {
poodle: {
first: {
hey: 'you'
},
second: 'meAgain'
}
};
movePropertyUpALevel(fakeObj, 'poodle');
console.log(fakeObj.first.hey);
//'you'
console.log(fakeObj.poodle);
//undefined
obj =
[
{"field" : "DEPARTMAN_NO",
"data" : { "type":"numeric" , "comparison":"eq" , "value":11 }
},
{"field" : "DEPARTMAN_ADI",
"data" : { "type":"string" , "value":"bir" }
}
];
for ( var item in obj ) {
if ( obj[item].field && obj[item].data ) { //check the 'field' and 'data' exist
obj[item].field = {
dept : obj[item].field , //department name is put into a property
type : obj[item].data.type, //so is data.type and data.value..
value: obj[item].data.value //..all are now contained in 'field'
};
delete obj[item].data; //remove the 'data' object
}
}
console.log(obj);
department.type = department.data.type;
department.value = department.data.value;
delete department['data'];
What is the best way to filter JSON nested keys and delete them? For example:
{ "id" : "1",
"key1" : "val1",
"key2" : "val2",
"name" : "someone",
"age" : 39,
"data" : [
{ "id" : "1234",
"key1" : "val1",
"key2" : "val2",
"name" : "someone",
"age" : 39
},
{ "id" : "1234",
"key1" : "val1",
"key2" : "val2",
"name" : "someone",
"age" : 39
}
]
}
To get the following JSON by deleting all key1 and key2 items recursively:
{ "id" : "1",
"name" : "someone",
"age" : 39,
"data" : [
{ "id" : "1234",
"name" : "someone",
"age" : 39
},
{ "id" : "1234",
"name" : "someone",
"age" : 39
}
]
}
Thanks.
Something like this should work:
function deleteRecursive(data, key) {
for(var property in data) {
if(data.hasOwnProperty(property)) {
if(property == key) {
delete data[key];
}
else {
if(typeof data[property] === "object") {
deleteRecursive(data[property], key);
}
}
}
}
}
Fiddle here
Assuming this is the JSON for an object called, say, people, something like this should work:
function objWithoutPropsIDontLike(obj, propsIDontLike) {
// check to make sure the given parameter is an object
if(typeof obj == "object" && obj !== null) { // typeof null gives "object" ಠ_ಠ
// for every property name... (see note on Object.keys() and
// Array.forEach() below)
obj.keys().forEach(function(prop) {
// Test if the property name is one of the ones you don't like
// (Array.indexOf() returns -1 if the item isn't found in the array).
if(propsIDontLike.indexOf(prop) >= 0) {
// if it is, nuke it
delete obj[prop];
} else if(obj[prop]) {
// if it isn't, recursively filter it
obj[prop] = filterPropsIDontLike(obj[prop], propsIDontLike);
}
});
}
// There is no else { ... }; if the thing given for "obj" isn't an object
// just return it as-is.
return obj;
}
var propsIDontLike = [ 'key1', 'key2' ];
people = objWithoutPropsIDontLike(people, propsIDontLike);
Note:
Object.keys() and Array.forEach() aren't available in Internet Explorer < 9. Happily MDC provides working polyfills for both: Object.keys(), Array.forEach().
Your question contains your answer: recursively!
Your base cases are the "primitive" JSON types: strings and numbers. These remain unchanged. For arrays, you apply the operation to each element of the array, returning a new array.
The interesting case is objects. Here, for each key-value pair, you apply the operation to each value (but ignore those whose key is one you would like to "delete") and write them into a new object.
As an (off the cuff) example, using jQuery:
var removeKey(object, key){
if(typeof(object)==='number' || typeof(object)==='string'){
return object;
}
else if(typeof(object)==='object'){
var newObject = {};
$.each(object, function(k, value) {
if(k!==key){
newObject[k] = removeKey(value, key);
}
});
return newObject;
}
else {
// Oh dear, that wasn't really JSON!
}
};
If you want to remove more than one key, adjust the second parameter and condition in the recursive case as you see fit.
NOTE This is a non-destructive, which may or may not be what you need; the other answer (by Vivin Paliath) has a destructive version.