Group json object in javascript - javascript

I want to group json array by first letter
This is my data records it quesry from sqlitedb
Ex :
[
{"pid":2,"ID":1,"title":"aasas as"},
{"pid":3,"ID":2,"title":"family"},
{"pid":4,"ID":3,"title":"fat111"}
]
I need this output
{
A: [{
title: "aasas as",
ID: 1
}],
F: [{
title: "family",
ID: 2
}, {
title: "fat111",
ID: 3
}]
}

Try this
var data = [
{"pid":2,"ID":1,"title":"aasas as"},
{"pid":3,"ID":2,"title":"family"},
{"pid":4,"ID":3,"title":"fat111"}
];
var result = {},
i,
len = data.length,
key;
for (i = 0; i < len; i++) {
key = data[i].title.substring(0, 1); // get first word from string
if (!result[key]) { // if key does not exists in result, create it
result[key] = [];
}
result[key].push(data[i]); // else push data
}
console.log(result);

Related

how to count duplicate values object to be a value of object

how to count the value of object in new object values
lets say that i have json like this :
let data = [{
no: 3,
name: 'drink'
},
{
no: 90,
name: 'eat'
},
{
no: 20,
name: 'swim'
}
];
if i have the user pick no in arrays : [3,3,3,3,3,3,3,3,3,3,3,90,20,20,20,20]
so the output should be an array
[
{
num: 3,
total: 11
},
{
num: 90,
total: 1
},
{
num:20,
total: 4
}
];
I would like to know how to do this with a for/of loop
Here is the code I've attempted:
let obj = [];
for (i of arr){
for (j of data){
let innerObj={};
innerObj.num = i
obj.push(innerObj)
}
}
const data = [{"no":3,"name":"drink"},{"no":90,"name":"eat"},{"no":20,"name":"swim"}];
const arr = [3,3,3,3,3,3,3,3,3,3,3,20,20,20,20,80,80];
const lookup = {};
// Loop over the duplicate array and create an
// object that contains the totals
for (let el of arr) {
// If the key doesn't exist set it to zero,
// otherwise add 1 to it
lookup[el] = (lookup[el] || 0) + 1;
}
const out = [];
// Then loop over the data updating the objects
// with the totals found in the lookup object
for (let obj of data) {
lookup[obj.no] && out.push({
no: obj.no,
total: lookup[obj.no]
});
}
document.querySelector('#lookup').textContent = JSON.stringify(lookup, null, 2);
document.querySelector('#out').textContent = JSON.stringify(out, null, 2);
<h3>Lookup output</h3>
<pre id="lookup"></pre>
<h3>Main output</h3>
<pre id="out"></pre>
Perhaps something like this? You can map the existing data array and attach filtered array counts to each array object.
let data = [
{
no: 3,
name: 'drink'
},
{
no:90,
name: 'eat'
},
{
no:20,
name: 'swim'
}
]
const test = [3,3,3,3,3,3,3,3,3,3,3,90,20,20,20,20]
const result = data.map((item) => {
return {
num: item.no,
total: test.filter(i => i === item.no).length // filters number array and then checks length
}
})
You can check next approach using a single for/of loop. But first I have to create a Set with valid ids, so I can discard noise data from the test array:
const data = [
{no: 3, name: 'drink'},
{no: 90, name: 'eat'},
{no: 20, name: 'swim'}
];
const userArr = [3,3,3,3,3,3,3,3,7,7,9,9,3,3,3,90,20,20,20,20];
let ids = new Set(data.map(x => x.no));
let newArr = [];
for (i of userArr)
{
let found = newArr.findIndex(x => x.num === i)
if (found >= 0)
newArr[found].total += 1;
else
ids.has(i) && newArr.push({num: i, total: 1});
}
console.log(newArr);

How to convert array of object into an array of object with different format?

I'm having an array of object,in which I'm storing the billkey and billvalue as attributes. I want billkey to be the key and billvalue to be the value of that particular key.
var log=[
{
billkey:"Name",
billvalue:"ABC"
},
{
billkey:"Department",
billvalue:"Computer"
}
{
billkey:"Name",
billvalue:"XYZ"
},
{
billkey:"Department",
billvalue:"Electrical"
}];
And I want to convert it into this format:
var log=[
{
Name:"ABC",
Department:"Computer"
},
{
Name:"XYZ",
Department:"Electrical"
}];
How about this simple solution. Hope it helps!
var log=[
{
billkey:"Name",
billvalue:"ABC"
},
{
billkey:"Department",
billvalue:"Computer"
},
{
billkey:"Name",
billvalue:"XYZ"
},
{
billkey:"Department",
billvalue:"Electrical"
}];
var arr = [];
var finalObj = [];
for(var i in log){
var someObject = log[i];
for(var j in someObject){
arr.push(someObject[j]);
}
}
for(var k = 0; k < arr.length; k+=4){
finalObj.push({
Name: arr[k+1],
Department: arr[k+3]
});
}
console.log(finalObj);
create the result using forloop
// store the values
var logs=[];
var log=[
{
billkey:"Name",
billvalue:"ABC"
},
{
billkey:"Department",
billvalue:"Computer"
},
{
billkey:"Name",
billvalue:"XYZ"
},
{
billkey:"Department",
billvalue:"Electrical"
},
];
loop the first array
for (i = 0; i < log.length; i++) {
// create empty variable for storing the values
var index = new Array();
// insert the first index value to key
index[log[i].billkey] = log[i].billvalue
// insert the second index value to key
index[log[i+1].billkey] = log[i+1].billvalue
// insert the result in to new array
logs.push(index);
// increment the i with 1
i=i+1;
}
console.log(logs);
You could use Array#reduce and use the remainder operator as witch for using either the last object or create a new one.
var log = [{ billkey: "Name", billvalue: "ABC" }, { billkey: "Department", billvalue: "Computer" }, { billkey: "Name", billvalue: "XYZ" }, { billkey: "Department", billvalue: "Electrical" }],
result = log.reduce(function (r, a, i) {
var o = {};
if (i % 2) {
r[r.length - 1][a.billkey] = a.billvalue;
} else {
o[a.billkey] = a.billvalue;
r.push(o);
};
return r;
}, []);
console.log(result);

Object Array Formatting

I have an object in this format:
var request = {
"student": [
[
"name",
"age"
],
[
"Tom",
12
],
[
"Jack",
13
]
]
};
I want to transform it into this:
var request = {
"student": [
{
"name": "Tom",
"age": 12
},
{
"name": "Jack",
"age": 13
}
]
}
I tried doing it this way:
var response = [];
var keysCount = req.result[0].length;
var responseCount = req.result.length - 1;
var i = 0,
j = 0,
key;
for (j = 0; j < responseCount; j++) {
for (i = 0; i < keysCount; i++) {
key = req.result[0][i];
response[j][key] = req.result[j + 1][i];
}
}
return response;
But, it is not working as expected.
It's a matter of looping through the first array and creating an array of objects for all the remaining arrays, using values at matching indexes to create properties on object:
var request = {
"student": [
[
"name",
"age"
],
[
"Tom",
12
],
[
"Jack",
13
]
]
};
// Get the header array
var headers = request.student[0];
// Create the new array but mapping the other entries...
var newArray = request.student.slice(1).map(function(entry) {
// Create an object
var newEntry = {};
// Fill it in with the values at matching indexes
headers.forEach(function(name, index) {
newEntry[name] = entry[index];
});
// Return the new object
return newEntry;
});
console.log(newArray);
I would make a small function tabularize that takes an array of data where the first element is an array of headers, and the remaining elements are the rows
Code that follows uses ES6. If you need ES5 support, you can safely transpile this code using a tool like babel.
// your original data
var request = {
"student": [
[
"name",
"age"
],
[
"Tom",
12
],
[
"Jack",
13
]
]
};
// tabularize function
var tabularize = ([headers, ...rows])=>
rows.map(row=>
headers.reduce((acc,h,i)=>
Object.assign(acc, {[h]: row[i]}), {}));
// your transformed object
var request2 = {student: tabularize(request.student)};
// log the output
console.log(request2);
//=> {"student":[{"name":"Tom","age":12},{"name":"Jack","age":13}]}
Or you can create the request object with the intended shape by passing the tabular data directly into the tabularize function at the time of object creation
// tabularize function
var tabularize = ([headers, ...rows])=>
rows.map(row=>
headers.reduce((acc,h,i)=>
Object.assign(acc, {[h]: row[i]}), {}));
// your request object
var request = {
student: tabularize([
[
"name",
"age"
],
[
"Tom",
12
],
[
"Jack",
13
]
])
};
// log the output
console.log(request);
//=> {"student":[{"name":"Tom","age":12},{"name":"Jack","age":13}]}
Let's start off by writing a little function just to create an object from two arrays, one of keys and one of their values:
function makeObjectFromPairs(keys, values) {
var object = {};
for (var i = 0; i < keys.length; i++) {
object[keys[i]] = values[i];
}
return object;
}
// makeObjectFromPairs(['a', 'b'], [1, 2]) === {a: 1, b: 2}
Now we can use the first element of the students array as the keys, and each of the remaining elements as the values.
var keys = students[0];
var result = [];
for (var i = 1; i < students.length; i++) {
result.push(makeObjectFromPairs(keys, students[i]);
}
You could use Array#map etc. as an alternative for the loops, but perhaps this basic approach is more accessible.
Fixing your original code
Since you made a valiant effort to solve this yourself, let's review your code and see where you went wrong. The key point is that you are not initializing each element in your output to an empty object before starting to add key/value pairs to it.
for (j = 0; j < responseCount; j++) {
// Here, you need to initialize the response element to an empty object.
response[j] = {};
Another solution :
var request = {
"student": [
[
"name",
"age"
],
[
"Tom",
12
],
[
"Jack",
13
]
]
};
var response = {};
var students = [];
var responseCount = request.student.length - 1;
var j = 0,
key;
for (j = 0; j < responseCount; j++) {
var student = {};
request.student[0].forEach(function(name, index) {
student[name] = request.student[1 + j][index];
});
students.push(student)
}
response["students"] = students;
console.log(response); // {"students":[{"name":"Tom","age":12},{"name":"Jack","age":13}]}
Lodash solution
var keys = _.head(request.student);
var valueGroups = _.flatten(_.zip(_.tail(request.student)));
var studentObjects = valueGroups.map(function(values){
return values.reduce(function(obj, value, index){
obj[keys[index]] = value;
return obj;
}, {});
});
console.log(studentObjects);
https://jsfiddle.net/mjL9c7wt/
Simple Javascript solution :
var request = {
"student": [
[
"name",
"age"
],
[
"Tom",
12
],
[
"Jack",
13
]
]
};
var students = [];
for(var x = 1; x<request.student.length;x++)
{
var temp = { 'name' : request.student[x][0],
'age' : request.student[x][1]
}
students.push(temp);
}
request = { 'students' : students}
console.log(request);

How to merge objects using JavaScript?

I have the below
$scope.Marketing = [{
'ProductId':1,
'ProductName':'Product 1',
'ProductDescription':'Product Description 1'
},
{
'ProductId':2,
'ProductName':'Product 2',
'ProductDescription':'Product Description 2'
}];
$scope.Finance=[{
'ProductId':1,
'Price':'$200.00'
},
{
'ProductId':2,
'Price':'$100.00'
}];
$scope.Inventory=[{
'ProductId':1,
'StockinHand:':26
},
{
'ProductId':2,
'StockinHand':40
}];
I want the output to be
My Merge function is here
$scope.tempresult=merge($scope.Marketing,$scope.Finance);
$scope.result=merge($scope.tempresult,$scope.Inventory);
function merge(obj1,obj2){ // Our merge function
var result = {}; // return result
for(var i in obj1){ // for every property in obj1
if((i in obj2) && (typeof obj1[i] === "object") && (i !== null)){
result[i] = merge(obj1[i],obj2[i]); // if it's an object, merge
}else{
result[i] = obj1[i]; // add it to result
}
}
for(i in obj2){ // add the remaining properties from object 2
if(i in result){ //conflict
continue;
}
result[i] = obj2[i];
}
return result;
}
But the output is
The value for first Stock In Hand is missing.
What is the mistake I am making?
Edit
you could use Jquery.extend property, have a look at the plnkr code
$scope.result=merge($scope.Marketing, $scope.Finance,$scope.Inventory);
function merge(obj1,obj2, obj3){
return $.extend(true, obj1,obj2,obj3)
}
};
http://plnkr.co/edit/gKQ9bc?p=preview
One approach is populating the one array of products with missing properties from the other two (after matching with product id).
See: http://jsfiddle.net/zekbxh90/1/ - and check the console output
Code:
var a = [{
'ProductId': 1,
'ProductName': 'Product 1',
'ProductDescription': 'Product Description 1'
}, {
'ProductId': 2,
'ProductName': 'Product 2',
'ProductDescription': 'Product Description 2'
}];
var b = [{
'ProductId': 1,
'Price': '$200.00'
}, {
'ProductId': 2,
'Price': '$100.00'
}];
var c = [{
'ProductId': 1,
'StockinHand:': 26
}, {
'ProductId': 2,
'StockinHand': 40
}];
// lets add the props from b abd c into a to get the desired result
a.forEach(function (_itemA) {
// get product id in a
var productId = _itemA.ProductId,
matching = false,
prop = false;
// get the matching item in b and add new props to a
b.forEach(function (_itemB) {
if (_itemB.ProductId === productId) merge(_itemA, _itemB);
});
// get the matching item in c and add new props to a
c.forEach(function (_itemC) {
if (_itemC.ProductId === productId) merge(_itemA, _itemC);
});
});
console.log(a);
function merge(_to, _from) {
for (var prop in _from) {
if (!_to.hasOwnProperty(prop) && _from.hasOwnProperty(prop)) _to[prop] = _from[prop];
}
}

How can get all objects whose sub object's property matches my string array using linq.js?

I have an array of tag names:
var tags = ['tagOne', 'tagTwo']
Which I want to use, to query the array below and get all items which match a tag.
var items =
[
{
'name': 'itemOne',
'tags': [
{ name: 'tagOne' }
]
},
{
'name': 'itemTwo',
'tags': [
{ name: 'tagTwo' }
]
}
];
How can I do this with linq Js? I.E in this case both items would be returned
Try this; it may not be the most efficient way (I've never used linq.js before) but it will work:
// Enumerate through the items
var matches = Enumerable.From(items)
.Where(function(item) {
// Enumerate through the item's tags
return Enumerable.From(item.tags).Any(function(tag) {
// Find matching tags by name
return Enumerable.From(tags).Contains(tag.name);
})
})
.ToArray();
This should work for you:-
Items
var items =
[
{
'name': 'itemOne',
'tags': [
{ name: 'tagOne' }
]
},
{
'name': 'itemTwo',
'tags': [
{ name: 'tagTwo' }
]
},
{
'name': 'itemThree',
'tags': [
{ name: 'tagThree' }
]
}
];
Tags:-
var tags = ['tagOne', 'tagTwo'];
Search for Tags:-
var fillteredItems = items.filter(function(item){
var tagsInItem = item["tags"];
for (var i = 0; i < tags.length; i++) {
for (var j = 0; j < tagsInItem.length; j++) {
if(tags[i]==tagsInItem[j].name)
return item;
};
};
});
Print Results:-
fillteredItems.forEach(function(item){
console.log("items",item);
})

Categories