Reorder JSON with new key - javascript

I have a large JSON returned from a rest service and I need to sort it before I can use it.
Example lines:
[{"Time":"1354233600000","Name":"NAN","TagValue":"0","TagValue2":"0"},
{"Time":"1354234500000","Name":"NAN","TagValue":"0","TagValue2":"0.0020288255172466159"},
{"Time":"1354235400000","Name":"NAN","TagValue":"0","TagValue2":"0.0022446943714048121"},
{"Time":"1354236300000","Name":"NAN","TagValue":"0","TagValue2":"0.00014998416164500384"},
{"Time":"1354237200000","Name":"NAN","TagValue":"0","TagValue2":"0"},
{"Time":"1354238100000","Name":"NAN","TagValue":"0","TagValue2":"0.00015631034628383933"},
{"Time":"1354239000000","Name":"NAN","TagValue":"0","TagValue2":"1.1165024734559951E-05"}
There are about 2000 lines like this. I would like to sort them by time and get something like this:
var restData = { "1354234500000":[
{"Name":"NaN",
"TagValue":"0",
"TagValue2":"someFloat"}
{"Name:"NAN,
"TagValue":"0",
"TagVale":"0"}
],
"aNewUnixTimeStamp":[
{..........}
]};
Is there some magic javascript function that I can use to accomplish this?

var myarray = [{"Time":"1354233600000","Name":"NAN","TagValue":"0","TagValue2":"0"},
{"Time":"1354234500000","Name":"NAN","TagValue":"0","TagValue2":"0.0020288255172466159"},
{"Time":"1354235400000","Name":"NAN","TagValue":"0","TagValue2":"0.0022446943714048121"},
{"Time":"1354236300000","Name":"NAN","TagValue":"0","TagValue2":"0.00014998416164500384"},
{"Time":"1354237200000","Name":"NAN","TagValue":"0","TagValue2":"0"},
{"Time":"1354238100000","Name":"NAN","TagValue":"0","TagValue2":"0.00015631034628383933"},
{"Time":"1354239000000","Name":"NAN","TagValue":"0","TagValue2":"1.1165024734559951E-05"}
var result = myarray.reduce(function(res, obj) {
if (res.hasOwnProperty(obj.Time) === false) {
res[obj.Time] = [];
}
res[obj.Time].push(obj);
delete obj.Time;
return res;
}, {});
You should be aware that since the result is using the timestamps as keys of an object you won't be able to sort them since objects have no defined order.
Also .reduce() will need a shim for older browsers. You can use the one provided by MDN.

Assuming your objects are all neatly organised in an array, you can just call
bigArray.sort(function(a,b) {return a.Time < b.Time ? -1 : 1})

you can also use this pligin from jquery
http://archive.plugins.jquery.com/project/sort
$(dataSet).sort("Time", "asc");

Related

How to get a value out of an array in typescript?

I have an array that looks like this
const array: any[] = []
array.push({ 'Comments': this.comment, 'Name': this.name, 'Description' : this.description })
I pass that array back to a parent component. How can I grab the value that is in Comments?
You can use forEach loop :
const commentArray = [];
array.forEach(function(object) {
var comment = object.Comments;
commentArray.push(comment);
});
//You can store all comments in another array and use it...
console.log("This is comment array...", commentArray);
Or use map but it will work in new browsers possibly ones following ES6:
const commentArray = array.map(function(object) {
return object.Comments;
});
console.log("This is comment array... ", commentArray);
As long as TGW's answer is "correct" and works, I think you should be aware of and use for...of (and for...in) construction, it's superior over Array.forEach (faster, you can use continue and break keywords, better readability) and more often you want to iterate over your array and do things with it, than just get one property (which Array.map is perfect for in this case :) )
You may try for this:
We can also use filter here.
let commentArray:any[];
array.filter(function(object) {
var comment = object.Comments;
commentArray.push(comment);
});
//Store here and use this.
console.log("This is comment array...", commentArray);
You can use Underscore JS for short and better performance like below:
let ids: Array<number> = _.map(this.mylist, (listObj) => {
return listObj.Id;
});

How to convert a JSON object to array of arrays

In my application I am getting a json result from the controller, which I want to turn to array of arrays in the frontend, so I can work with the google charts api.
Currently I am using a $.parseJSON(result) on the string I am getting, so in the end i get this in the console :
And what i'd like to get is :
Here is the initial json string, which i get before the parseJSON part :
[{"rolename":"some role","perc":45.5},{"rolename":"another role","perc":36.4},{"rolename":"role three","perc":9.1},{"rolename":"role four","perc":9.1}]
Any tips on how can i achieve that?
ES6 ( quite new cool stuff ):
var json=[{"rolename":"some role","perc":45.5},{"rolename":"another role","perc":36.4},{"rolename":"role three","perc":9.1},{"rolename":"role four","perc":9.1}];
var answer=json.map(el=>Object.values(el));
Working: http://jsbin.com/pejucoriqu/edit?console
ES5 ( compatible with a lot browsers):
var answer=json.map(function(el){
var arr=[];
for(var key in el){
arr.push(el[key]);
}
return arr;
});
Youve got an array of objects, And you want an array of arrays. So take each element and map it with the values of the object.
You can use map to change objects to arrays and also Object.keys and map to return only object values.
var data = [{"rolename":"some role","perc":45.5},{"rolename":"another role","perc":36.4},{"rolename":"role three","perc":9.1},{"rolename":"role four","perc":9.1}]
var result = data.map(function(e) {
return Object.keys(e).map(function(k) {
return e[k]
})
})
console.log(result)
Or with ES6 you can use arrow functions like this
var result = data.map(e => Object.keys(e).map(k => e[k]))

Get the difference between two arrays of objects

I've got two arrays of objects, the difference between them is only that arrayAfter will have an element added:
var arrayBefore = [
{"name":"Alan","height":"171","weight":"66"},
{"name":"Ben","height":"182","weight":"90"}
];
var arrayAfter= [
{"name":"Alan","height":"171","weight":"66"},
{"name":"Ben","height":"182","weight":"90"},
{"name":"Chris","height":"163","weight":"71"}
];
"name" is always unique!
How can I find out which one is the element that has been added? I've tried ending up using nested for loops, but this seems overcomplicated.
I've also found the this nice idea:
var diff = $(arrayAfter).not(arrayBefore ).get();
However, that does not seem to work on arrays of objects straight ahead.
Is there some easy way to get the difference?
If only the name indicates uniqueness, you can do:
//Get a list of all the names in the before array
var beforeNames = arrayBefore.map(function(person) { return person.name });
//Filter the after array to only contain names not contained in the before array
var uniqueObjects = arrayAfter.filter(function(person) {
return beforeNames.indexOf(person.name) === -1;
});
console.log(uniqueObjects); //[{"name":"Chris","height":"163","weight":"71"}]
Demo: http://jsfiddle.net/tehgc8L5/
For a generic method you can combine Array.prototype.filter() with Array.prototype.reduce() which iterates over the object keys:
arrayAfter.filter(function(after) {
return !arrayBefore.reduce(function(found, before) {
if (!found) {
found = true;
for (key in before) {
if (before.hasOwnProperty(key)) {
found = found && (before[key] === after[key]);
}
}
}
return found;
}, false);
}); //[{name: "Chris", height: "163", weight: "71"}]
You can use Array.prototype.filter and filter out those elements in the previous array.
var differences = arrayAfter.filter(function(el) {
return arrayBefore.indexOf(el) === -1;
});
I believe jQuery will have nothing that will directly solve your problem here. Your problem being comparing objects for equality.
I am assuming that name is unique. If not, for this method you will need a unique identifier for data. If you absolute do not have one then you could concat all data to get one.
// first make a map of objects in before
var before = {};
arrayBefore.forEach(function(o){
before[o.name] = o;
});
// now we get the elements of after that do not exist in our hashmap
var result = arrayAfter.filter(function(o){
return !(o.name in before);
});
You can obviously wrap this up in a general function.

Filtering thru an array and returning a new array with matching pattern

I'm trying to filter an array and return a new array with the matching elements.
So for example
var names = ["Kanye, West","Drake, Ross", "Rick, Boss", "Steven, Ross"];
function filterName(arr,pattern){
//logic here
return newArr
}
filterName(names,"ss"); //output ["Drake, Ross", "Rick, Boss", "Steven, Ross"];
Can someone point me in the right direction? Do I need regex to get something like this to work?
Thank you for reading!
Looks like you want to create the RegEx dynamically.
You should be creating new RegExp() object and passing the pattern to it so we can use it with .test() method.
Working code snippet:
var names = ["Kanye, West","Drake, Ross", "Rick, Boss", "Steven, Ross"];
function filterName(arr, pattern){
pattern = new RegExp(pattern); // create a RegExp object with dynamically added pattern
var newArr = []; // initialize new array for storing results
arr.forEach(function(item){ // parse the array
if(pattern.test(item)) // if passes the regex test
newArr.push(item); // add to result array
});
return newArr;
}
// test our function 'filterName'
// test for 'ss'
console.log("Searching for 'ss'");
var result = filterName(names,"ss"); //output ["Drake, Ross", "Rick, Boss", "Steven, Ross"];
console.dir(result);
// test for 'West'
console.log("Searching for 'West'");
var result1 = filterName(names,"West"); //output ["Kanye, West"];
console.dir(result1);
Learn more:
RegExp | MDN
RegExp.prototype.test() - JavaScript | MDN
Use the Array.filter method - it's native (to modern browsers), requires no libraries.
var names = ["Kanye, West","Drake, Ross", "Rick, Boss", "Steven, Ross"];
function filterName(arr,pattern){
return arr.filter(function(item) {
return item.indexOf(pattern) > -1;
});
}
var result = filterName(names,"ss"); //output ["Drake, Ross", "Rick, Boss", "Steven, Ross"];
document.write(JSON.stringify(result));
You can use jQuery grep:
https://api.jquery.com/jQuery.grep/
Description: Finds the elements of an array which satisfy a filter function. The original array is not affected.
You can use the Underscore.js library. Specifically the Filter function.
http://underscorejs.org/#filter
it would go something like this
_.filter(myArray, function(names){
return names.indexOf("somePatternHere") !== -1;
});
For whichever values in the array return true will be included in the new array that is return with the "filtered" values.
There's also the Lo-dash library at https://lodash.com/
A reason I'd recommend using one of these libraries (probably Lodash actually) is they are optimized per the browser being utilized. Different browsers respond to native functions slightly differently and if you want the best results using one of these two is the best option.
Plus, it's a good habit to use these anyway since JavaScript lacks many basic functions that other libraries have already.

using underscore to compare two object lists and obtain the unique objects

We have 2 JavaScript object lists.
var AList = [{id:1,name:"AA"},{id:2,name:"BB"},{id:3,name:"CC"},{id:4,name:"DD"},{id:5,name:"EE"},{id:6,name:"FF"}]
var BList = [{id:1,name:"AA"},{id:2,name:"BB"},{id:3,name:"CC"},{id:4,name:"DD"}]
we need to eliminate the duplicates from both lists and return what is unique for AList. (id 5 and 6)
I've used a generic JavaScript implementation for this, but I like to implement a more sleek solution based on underscore.
for(var i=0;i<AList.length;i++){
for(var j=0;j<fBList.length;j++){
if(AList[i] && fBList[j] && (AList[i].id == BList[j].id)){
delete AList[i];
}
}
}
var uniqueList= _.uniq(AList);
After A list is done with deleting the duplicates, there are null elements in place where the duplicates were, therefore we needed to use _uniq to get a unique set of values.
_.difference(AList,BList)
Doesn't provide the answer.
You could combine the two arrays, then get the unique result.
var uniqueList = _.uniq(AList.concat(BList), function(item) {
return item.id;
});
Or you could use _.property(key):
var uniqueList = _.uniq(AList.concat(BList), _.property('id'));
Unfortunately _.difference does use strict equality, and there is no way to change that by a custom equality callback. You still need to compute it manually:
AList = _.uniq(AList, _.property('id'));
BList = _.uniq(BList, _.property('id'));
var bIds = _.pluck(BList, "id");
_.filter(AList, function(el) { return !_.contains(bIds, el.id); })
For those who stumble on this as I did, lodash now has a function called differenceWith which takes a comparator.
_.differenceWith(array, [values], [comparator])
https://lodash.com/docs#differenceWith

Categories

Resources