How to group objects into one object in underscore - javascript

How to convert this :
[
{name: 'foo', type: 'product'},
{name: 'bar', type: 'product'},
{name: 'john', type: 'product'},
{name: 'no name', type: 'product'},
]
How can i group and get all the objects without name:'no name' as separate Object like this:
{
0:[
{name: 'foo', type: 'product'},
{name: 'bar', type: 'product'},
{name: 'john', type: 'product'}
],
1:[
{name: 'no name', type: 'product'},
]
}

To produce an object with keys 0 and 1, use _.groupBy:
var objectResult = _.groupBy(data, function(d) { return +(d.name === "no name") })
To produce an array with two elements (which will also have keys 0 and 1) you could use _.partition (Underscore 1.6.0 +):
partition_.partition(array, predicate): Split array into two arrays:
one whose elements all satisfy predicate and one whose elements all do
not satisfy predicate.
var arrayResult = _.partition(data, function(d) { return d.name !== "no name" })
JSBin

As a comparison, plain ECMAScript takes just a little more code:
data.reduce(function(acc, obj) {
acc[obj.name == 'no name'? 1:0].push(obj);
return acc;},{0:[],1:[]}
);

You can try http://underscorejs.org/#groupBy:
var data = [
{name: 'foo', type: 'product'},
{name: 'bar', type: 'product'},
{name: 'john', type: 'product'},
{name: 'no name', type: 'product'},
]
var results = _.groupBy(data, function(obj) { return obj.name == 'no name' ? 1 : 0; })
console.log(results)

You can try like that.
var arr = [
{name: 'foo', type: 'product'},
{name: 'bar', type: 'product'},
{name: 'john', type: 'product'},
{name: 'no name', type: 'product'},
];
var result = _.groupBy(arr, function (elem) {
return elem.name == 'no name' ? 1: 0;
});

Why use a framework for such a simple thing ?
Here is a pure JS solution allowing to groupBy properly.
It is then easy to work with the result object.
var array=[
{name: 'foo', type: 'product'},
{name: 'bar', type: 'product'},
{name: 'john', type: 'product'},
{name: 'no name', type: 'product'},
{name: 'foo', type: 'product'},
{name: 'bar', type: 'product'},
{name: 'john', type: 'product'},
{name: 'no name', type: 'product'},
{name: 'no name', type: 'product'},
{name: 'no name', type: 'product'},
{name: 'no name', type: 'product'},
];
function groupBy(propertyName, array) {
var groupedElements = {};
for (var i = 0, len = array.length; i < len; i++) {
var el = array[i];
var value = el[propertyName].trim();
var group = groupedElements[value];
if (group === undefined) {
group = [el];
groupedElements[value] = group;
} else {
group.push(el);
}
}
return groupedElements;
}
var result = groupBy('name',array);

Related

Adding single quotes to values in object (javascript)

I have a string like this :
"[ {name: foo, type: int}, {name: status, type: string},
{name: boo, type: string}, {name: koo, type: data} ]"
and i need to add single quotes for values inside every object , to become like this string :
"[ {name: 'foo', type: 'int'}, {name: 'status', type:
'string'}, {name: 'boo', type: 'string'}, {name: 'koo',
type: 'data'} ]"
i have tried to use eval , JSON.parse , but didn't see the expected result , is there any idea to do this and just add the single quotes for values in objects ?
This is the whole JSON , but i only need the fields part .
{
"success": true,
"count": 1,
"data": [
{
"res": "extend: 'someCode', fields: [ {name: foo, type: int},
{name: status, type: string},
{name: boo, type: string}, {name: koo, type: data} ]"
}
]
}
Here's a way to do it with a regex:
const val = `[ {name: foo, type: int}, {name: status, type: string},
{name: boo, type: string}, {name: koo, type: data} ]`
console.log(val.replace(/(\w+)\s*\:\s*(\w+)/g, "$1: '$2'"))
Seems to produce a valid javascript array:
> eval(val.replace(/(\w+)\s*\:\s*(\w+)/g, "$1: '$2'"))
[ { name: 'foo', type: 'int' },
{ name: 'status', type: 'string' },
{ name: 'boo', type: 'string' },
{ name: 'koo', type: 'data' } ]
Might have to tweak it to suit your use case.
Here are the tweaks needed to fix Richard's code
let val = `[ {name: foo, type: int}, {name: status, type: string}, {name: boo, type: string}, {name: koo, type: data} ]`
val = val.replace(/(\w+)\s*\:\s*(\w+)/g, "\"$1\": \"$2\"")
console.log(JSON.parse(val))
Here is a correct JS object from the "JSON" you posted
{
"success": "true",
"count": 1,
"data": [{
"res": { "extend": "someCode" },
"fields": [
{"name": "foo", "type": "int"},
{"name": "status", "type": "string"},
{"name": "boo", "type": "string"},
{"name": "koo", "type": "data" }
]
}
]
}
Regexp replacement may be easy for this.
var s = "[ {name: foo, type: int}, {name: status, type: string}, {name: boo, type: string}, {name: koo, type: data} ]";
console.log(s.replace(/:[ ]*([^ ,}]+)/gi, ": '$1'"));
> "[ {name: 'foo', type: 'int'}, {name: 'status', type: 'string'}, {name: 'boo', type: 'string'}, {name: 'koo', type: 'data'} ]"
Please see below too.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace

JS split array of objects by object field

I have an array of tokens:
[
{type: 'name', value: 'foo'},
{type: 'string', value: 'bar'},
{type: 'special', value: ','},
{type: 'name', value: 'buzz'}
]
And I'd like to split them by value equal to ,:
[
[
{type: 'name', value: 'foo'},
{type: 'string', value: 'bar'}
],
[
{type: 'name', value: 'buzz'}
]
]
How should I do it?
You can use Array.reduce() to iterate the items. There are three cases:
The item's value is , - add a new sub-array without the item.
There is no sub-array - add a new sub-array with the item.
The rest - add the item to the last sub-array.
const data = [
{type: 'name', value: 'foo'},
{type: 'string', value: 'bar'},
{type: 'special', value: ','},
{type: 'name', value: 'buzz'}
];
const result = data.reduce((r, o) => {
if(o.value === ',') return [...r, []];
if(!r.length) return [[o]];
r[r.length - 1].push(o);
return r;
}, []);
console.log(result);
Using forEach
let arr = [
{type: 'name', value: 'foo'},
{type: 'string', value: 'bar'},
{type: 'special', value: ','},
{type: 'name', value: 'buzz'}
]
let op = [];
let temp = [];
arr.forEach((e,i)=>{
if(e.value === ',' && temp.length){
op.push(temp);
temp =[];
} else {
temp.push(e);
}
});
if(temp.length) op.push(temp);
console.log(op);

Angular 2 add key and value to each array object

I have array of objects :
array = [
{name: 'name'},
{name: 'name'},
{name: 'name'},
{name: 'name'},
]
I want to add key: '123' to each of them so it would be :
array = [
{name: 'name', key: '123'},
{name: 'name', key: '123'},
{name: 'name', key: '123'},
{name: 'name', key: '123'},
]
What I've tryed :
checked = false;
this.editObj.forEach(item => item.push(this.checked))
ERROR : item.push is not a function.
But it isn't working. How to do it in the right way ?
const arr = [
{name: 'name'},
{name: 'name'},
{name: 'name'},
{name: 'name'},
]
const arr2 = arr.map(x => ({...x , key: '123'}));
You can try with creating custom dictionary
array = [
{name: 'name'},
{name: 'name'},
{name: 'name'},
{name: 'name'},
]
var dict = []; // create an empty dictionary
for (i = 0; i < array.length; i++) {
dict.push({
key: "123",
value: array[i].name
});
}
console.log(dict);
you should do :
this.editObj.forEach(item => item["key"]= "123");
console.log(this.editObj);
Your code is not working because you use .push() on object, not on array.
Try this:
this.editObj.forEach(item => item["key"] = this.checked);
In everything except IE11
Creating a new array
const array = [{
name: 'name',
},
{
name: 'name',
},
{
name: 'name',
},
{
name: 'name',
},
];
console.log(array.map(x => ({
...x,
key: '123',
})));
Updating existing array
const array = [{
name: 'name',
},
{
name: 'name',
},
{
name: 'name',
},
{
name: 'name',
},
];
array.forEach((x) => {
x.key = '123';
});
console.log(array);
In IE11
var array = [{
name: 'name',
},
{
name: 'name',
},
{
name: 'name',
},
{
name: 'name',
},
];
for (var i = 0; i < array.length; i += 1) {
array[i].key = '123';
}
console.log(array);

How can I dynamically extend an object?

This is an example of data to use for a jquery library, however my data is dymanic and not hard coded.
var tree_data = {
'for-sale' : {name: 'For Sale', type: 'folder'} ,
'vehicles' : {name: 'Vehicles', type: 'folder'} ,
'rentals' : {name: 'Rentals', type: 'folder'} ,
'real-estate' : {name: 'Real Estate', type: 'folder'} ,
'pets' : {name: 'Pets', type: 'folder'} ,
'tickets' : {name: 'Tickets', type: 'item'} ,
'services' : {name: 'Services', type: 'item'} ,
'personals' : {name: 'Personals', type: 'item'}
}
So, My question is if I have this for example:
var tree_data = {
'for-sale' : {name: 'For Sale', type: 'folder'} ,
'vehicles' : {name: 'Vehicles', type: 'folder'}
}
How would I add
rentals' : {name: 'Rentals', type: 'folder'} ,
'real-estate' : {name: 'Real Estate', type: 'folder'}
To tree_data after its already created?
I also need to do this for this code, if you could possibly provide an example for both.
tree_data['for-sale']['additionalParameters'] = {
'children' : {
'appliances' : {name: 'Appliances', type: 'item'},
'arts-crafts' : {name: 'Arts & Crafts', type: 'item'},
'clothing' : {name: 'Clothing', type: 'item'},
'computers' : {name: 'Computers', type: 'item'},
'jewelry' : {name: 'Jewelry', type: 'item'},
'office-business' : {name: 'Office & Business', type: 'item'},
'sports-fitness' : {name: 'Sports & Fitness', type: 'item'}
}
}
If you're using jQuery.... try using $.extend()
http://api.jquery.com/jQuery.extend/
Otherwise...
var tree_data = {
'for-sale' : {name: 'For Sale', type: 'folder'} ,
'vehicles' : {name: 'Vehicles', type: 'folder'}
};
tree_data['rentals'] = {name: 'Rentals', type: 'folder'};
tree_data['real-estate'] = {name: 'Real Estate', type: 'folder'};

Extend from custom model class in ExtJS 4

How to extend from custom model in extjs.
Is there any method which can directly club the fields of User and BusinessUser fields when I'll refer the fields from BusinessUser class in example below.
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{name: 'name', type: 'string'},
{name: 'age', type: 'int'},
{name: 'phone', type: 'string'},
{name: 'alive', type: 'boolean', defaultValue: true}
],
});
Ext.define('BusinessUser', {
extend: 'User',
fields: [
{name: 'businessType', type: 'string'},
{name: 'company', type: 'string'}
],
});
You don't need to join the fields manually because it's done automatically. Check the outputs in the code bellow based on your question:
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{name: 'name', type: 'string'},
{name: 'age', type: 'int'},
{name: 'phone', type: 'string'},
{name: 'alive', type: 'boolean', defaultValue: true}
],
});
Ext.define('BusinessUser', {
extend: 'User',
fields: [
{name: 'businessType', type: 'string'},
{name: 'company', type: 'string'}
],
});
// instantiating a User object
var u = Ext.create('BusinessUser', {
name: 'John Doe',
age: 30,
phone: '555-5555'
});
// instantiating a BusinessUser object
var bu = Ext.create('BusinessUser', {
name: 'Jane Doe',
age: 40,
phone: '555-5556',
businessType: 'analyst',
company: 'ACME'
});
console.log(Ext.getClassName(bu)); // "BusinessUser"
console.log(Ext.getClassName(u)); // "User"
console.log(u instanceof User); // true
console.log(bu instanceof User); // true
console.log(u instanceof BusinessUser); // false
console.log(bu instanceof BusinessUser); // true
console.log(u instanceof Ext.data.Model); // true
console.log(bu instanceof Ext.data.Model); // true
console.log(u instanceof Ext.data.Store); // false, just to check if it's not returning true for anything
console.log(bu instanceof Ext.data.Store); // false
console.log("name" in u.data); // true
console.log("name" in bu.data); // true
console.log("company" in u.data); // false
console.log("company" in bu.data); // true
Although it should work automatically, use the below if you are having troubles for some reason.
Use the constructor to join the fields:
Ext.define('BusinessUser', {
extend : 'User',
constructor : function(){
this.callParent(arguments);
this.fields.push([
{name: 'businessType', type: 'string'},
{name: 'company', type: 'string'}
]);
}
});

Categories