Create nested object from serializeArray - javascript

I'd like to create this structure:
{
"officine_type": "Pharmacie",
"officine_value": 2002626,
"declared_lines": [
{
"ean": 3578835501148,
"qty": 1
},
{
"ean": 3578835502671,
"qty": 2
}
],
"other_value": "my other value"
}
From a serializeArray() with this output:
0: {name: 'declared_lines.0.ean', value: '3578835502244'}
1: {name: 'declared_lines.0.qty', value: '4'}
2: {name: 'declared_lines.1.ean', value: '3578835502220'}
3: {name: 'declared_lines.1.qty', value: '1'}
4: {name: 'declared_lines.2.ean', value: ''}
5: {name: 'declared_lines.2.qty', value: '0'}
6: {name: 'officine_type', value: 'Pharmacy'}
7: {name: 'officine_value', value: '2000461'}
8: {name: 'other_value', value: ''}
I'm struggling on how to push sub-objects in declared_lines
Right now i have this:
let formData = form.serializeArray();
for (let i = 0; i < formData.length; i++) {
if (formData[i]['name'].indexOf('declared_lines') !== 1) {
let inputName = formData[i]['name'].split('.');
let namespace = inputName[0];
let n = inputName[1];
let key = inputName[2];
let subObj = {};
let current = 'declared_lines['+i+']';
let previous = 'declared_lines['+(i-1)+']';
if (obj.hasOwnProperty(namespace) === false) {
obj[namespace] = [];
}
}
obj[formData[i]['name']] = formData[i]['value'];
}
My brain won't go further :(

You could take the name and split it by dot for the path of the new object and the value and build a new object with the given information.
In setValue, the reduce callback checks if the next key is a stringed numerical value and takes an array as default object instead of an object.
function setValue(object, path, value) {
const last = path.pop();
path
.reduce((o, k, i, kk) => o[k] ??= (isFinite(i + 1 in kk ? kk[i + 1] : last) ? [] : {}), object)
[last] = value;
return object;
}
const
data = [{ name: 'declared_lines.0.ean', value: '3578835502244' }, { name: 'declared_lines.0.qty', value: '4' }, { name: 'declared_lines.1.ean', value: '3578835502220' }, { name: 'declared_lines.1.qty', value: '1' }, { name: 'declared_lines.2.ean', value: '' }, { name: 'declared_lines.2.qty', value: '0' }, { name: 'officine_type', value: 'Pharmacy' }, { name: 'officine_value', value: '2000461' }, { name: 'other_value', value: '' }],
result = data.reduce(
(object, { name, value }) => setValue(object, name.split('.'), value),
{}
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Object destructuring and array.reduce can make your code more readable, try:
let formData = [
{name: 'declared_lines.0.ean', value: '3578835502244'},
{name: 'declared_lines.0.qty', value: '4'},
{name: 'declared_lines.1.ean', value: '3578835502220'},
{name: 'declared_lines.1.qty', value: '1'},
{name: 'declared_lines.2.ean', value: ''},
{name: 'declared_lines.2.qty', value: '0'},
{name: 'officine_type', value: 'Pharmacy'},
{name: 'officine_value', value: '2000461'},
{name: 'other_value', value: ''}
];
let output = formData.reduce((acc,cur) => {
let { name, value } = cur;
if(name.indexOf('declared_lines') === -1){
acc[name] = value;
} else {
let [namespace, n, key] = name.split('.');
if(!acc[namespace]) acc[namespace] = [];
if(!acc[namespace][n]) acc[namespace][n] = {};
acc[namespace][n][key] = value;
}
return acc;
}, {});
console.log(output);
In this case reduce starts with an empty object and it loops over your array to process each element (cur).

Related

Json conversion from one form to another

I want to convert this JSON to the format mentioned in the result section.
[
{ name: "FieldData[FirstName][Operator]", value: "=" }
{ name: "FieldData[FirstName][Value]", value: "test" }
{ name: "FieldData[LastName][Operator]", value: "=" }
{ name: "FieldData[LastName][Value]", value: "test" }
]
Result:
FieldData
{
FirstName {
Operator: =,
Value: tset
},
LastName {
Operator: =,
Value: tset
}
}
Using String.prototype.split function and regex, you can extract the strings inside [] and based on that data, you can generate the nested objects as follows.
const input = [
{name: "FieldData[FirstName][Operator]", value: "="},
{name: "FieldData[FirstName][Value]", value: "test"},
{name: "FieldData[LastName][Operator]", value: "="},
{name: "FieldData[LastName][Value]", value: "test"}
];
const result = input.reduce((acc, cur) => {
const keys = cur.name.split(/\[(.*?)\]/).filter((item) => item);
let item = acc;
for (let index = 0; index < keys.length - 1; index ++) {
const key = keys[index];
if (!(key in item)) {
item[key] = {};
}
item = item[key];
}
item[keys[keys.length - 1]] = cur.value;
return acc;
}, {});
console.log(result);
Using a regex and javascript's ability to set properties using obj[propname] = value as the same as obj.propname = value
var d = [
{ name: "FieldData[FirstName][Operator]", value: "=" },
{ name: "FieldData[FirstName][Value]", value: "test" },
{ name: "FieldData[LastName][Operator]", value: "=" },
{ name: "FieldData[LastName][Value]", value: "test" },
];
var r = {};
for (var i=0; i<d.length; ++i)
{
var parts = d[i].name.match(/(.*)\[(.*)\]\[(.*)\]/)
r[parts[1]] = r[parts[1]] || {};
r[parts[1]][parts[2]] = r[parts[1]][parts[2]] || {};
r[parts[1]][parts[2]][parts[3]] = d[i].value;
}
console.log(r)
(note: SO console JSONifies the object, look in the browser console for the object)

Can we assign an object key to another variable like this? [duplicate]

Given a JavaScript object, how can I convert it into an array of objects (each with key, value)?
Example:
var data = { firstName: 'John', lastName: 'Doe', email: 'john.doe#gmail.com' }
resulting like:
[
{ key: 'firstName', value: 'John' },
{ key: 'lastName', value: 'Doe' },
{ key: 'email', value: 'john.doe#gmail.com' }
]
var data = { firstName: 'John', lastName: 'Doe', email: 'john.doe#gmail.com' }
var output = Object.entries(data).map(([key, value]) => ({key,value}));
console.log(output);
Inspired By this post
Using map function
var data = { firstName: 'John', lastName: 'Doe', email: 'john.doe#gmail.com' };
var result = Object.keys(data).map(key => ({ key, value: data[key] }));
console.log(result);
You can just iterate over the object's properties and create a new object for each of them.
var data = { firstName: 'John', lastName: 'Doe', email: 'john.doe#gmail.com' };
var result = [];
for(var key in data)
{
if(data.hasOwnProperty(key))
{
result.push({
key: key,
value: data[key]
});
}
}
The previous answer lead me to think there is a better way...
Object.keys(data).map(function(key) {
return { key, value: data[key] };
});
or in ES6 using arrow functions:
Object.keys(data).map((key) => ({ key, value: data[key] }));
Just make your life easier and use es6 syntax with a map
var output = Object.keys(data).map(key => {
return {
key: key,
value: data[key]
};
})
var result = [];
for(var k in data) result.push({key:k,value:data[k]});
Or go wild and make the key and value keys customizable:
module.exports = function objectToKeyValueArray(obj, keyName = 'key', valueName = 'value') {
return Object
.keys(obj)
.filter(key => Object.hasOwnProperty.call(obj, key))
.map(key => {
const keyValue = {};
keyValue[keyName] = key;
keyValue[valueName] = obj[key];
return keyValue;
});
};
An alternative method for doing this that works on multi level objects and does not use recursion.
var output = []
var o = {
x:0,
y:1,
z:{
x0:{
x1:4,
y1:5,
z1:6
},
y0:2,
z0:[0,1,2],
}
}
var defer = [ [ o ,[ '_root_' ] ] ]
var _defer = []
while(defer.length){
var current = defer.pop()
var root = current[1]
current = current[0]
for(var key in current ){
var path = root.slice()
path.push(key)
switch( current[key].toString() ){
case '[object Object]':
_defer.push( [ current[key] , path ] )
break;;
default:
output.push({
path : path ,
value : current[key]
})
break;;
}
}
if(!defer.length)
defer = _defer.splice(0,_defer.length)
}
[
{ path: [ '_root_', 'x' ], value: 0 },
{ path: [ '_root_', 'y' ], value: 1 },
{ path: [ '_root_', 'z', 'y0' ], value: 2 },
{ path: [ '_root_', 'z', 'z0' ], value: [ 0, 1, 2 ] },
{ path: [ '_root_', 'z', 'x0', 'x1' ], value: 4 },
{ path: [ '_root_', 'z', 'x0', 'y1' ], value: 5 },
{ path: [ '_root_', 'z', 'x0', 'z1' ], value: 6 }
]
const array = [
{ key: "key1", value: "value1" },
{ key: "key2", value: "value2" },
];
const obj = Object.fromEntries(array.map(item => [item.key, item.value]));
console.log(obj);
I would say to use npm package flat.
works amazing for nested objects and arrays.
var flatten = require('flat')
flatten({
key1: {
keyA: 'valueI'
},
key2: {
keyB: 'valueII'
},
key3: { a: { b: { c: 2 } } }
})
// {
// 'key1.keyA': 'valueI',
// 'key2.keyB': 'valueII',
// 'key3.a.b.c': 2
// }
const array = [
{ key: "key1", value: "value1" },
{ key: "key2", value: "value2" },
];
const obj = Object.fromEntries(array.map(item => [item.key, item.value]));
console.log(obj);

Get count from Array of arrays

I have an array of arrays below. With ES6, how can I get a count of each value Good, Excellent & Wow into a new array e.g [{name: Good, count: 4} {name: Excellent, count: 5}, {name:Wow, count:2}] in dynamic style. I am attempting to use Object.assign but I am failing to "unique" out the count of the key plus instead, I need to use an array as I am trying to render this out on the front end. Do I need to use reduce? how?
let k = 0
const stats = {}
const remarks = [
[{name: "Good"}],
[{name: "Good"}, {name: "Excellent"}],
[{name: "Good"}, {name: "Excellent"}, {name: "Wow"}],
[{name: "Good"}, {name: "Excellent"}, {name: "Wow"}],
[{name: "Excellent"}],
[{name: "Excellent"}]
]
remarks.forEach((arr) => {
arr.map((e) => {
Object.assign(stats, { [e.name]: k = k + 1 })
})
})
console.log(stats);
Output:
stats: {Good: 8, Excellent: 11, Wow: 9}
Which is Incorrect plus I need to use an array.
Expected output:
[{name: Good, count: 4} {name: Excellent, count: 5}, {name:Wow, count:2}]
Flatten the array of arrays and reduce it starting with an object like : { Good: 0, Excellent: 0, Wow: 0}
then .map the Object.entries of the result to transform it to an array :
const remarks = [
[{ name: "Good" }],
[{ name: "Good" }, { name: "Excellent" }],
[{ name: "Good" }, { name: "Excellent" }, { name: "Wow" }],
[{ name: "Good" }, { name: "Excellent" }, { name: "Wow" }],
[{ name: "Excellent" }],
[{ name: "Excellent" }]
];
const result = Object.entries(
remarks.flat().reduce(
(all, { name }) => {
all[name] += 1;
return all;
},
{ Good: 0, Excellent: 0, Wow: 0 }
)
).map(([name, count]) => ({ name, count }));
console.log(result);
You can try below logic:
var data = [[{name: "Good"}],[{name: "Good"}, {name:"Excellent"}],[{name: "Good"}, {name:"Excellent"}, {name:"Wow"}],[{name: "Good"}, {name:"Excellent"}, {name:"Wow"}],[{name:"Excellent"}],[{name:"Excellent"}]]
var nData = [];
(data || []).forEach( e => {
(e || []).forEach(ei => {
var i = (index = nData.findIndex(d => d.name === ei.name)) >=0 ? index : nData.length;
nData[i] = {
name: ei.name,
count : (nData[i] && nData[i].count ? nData[i].count : 0)+1
}
});
});
console.log(nData);
Hope this helps!
You can use reduce, then convert the result into an array of objects:
const counts = remarks.reduce((result, list) => {
list.forEach(remark => {
result[remark.name] = (result[remark.name] || 0) + 1;
});
}, {});
const finalResult = [];
for (let name in counts) {
finalResult.push({name, count: counts[name]});
}
You could achieve this pretty easily by:
1) Flattening the nested array into 1 single level array.
2) Iterating over the flat array and create a "count map" by using Array.prototype.reduce
For example:
const remarks = [
[{
name: 'Good'
}],
[{
name: 'Good'
}, {
name: 'Excellent'
}],
[{
name: 'Good'
}, {
name: 'Excellent'
}, {
name: 'Wow'
}],
[{
name: 'Good'
}, {
name: 'Excellent'
}, {
name: 'Wow'
}],
[{
name: 'Excellent'
}],
[{
name: 'Excellent'
}]
]
const flatten = arr => arr.reduce((accum, el) => accum.concat(el), [])
const map = flatten(remarks).reduce((accum, el) => {
if (accum[el.name]) {
accum[el.name] += 1;
} else {
accum[el.name] = 1;
}
return accum;
}, {});
console.log(map)
First find the counts using reduce than pass that to another function to get the desired view structure:
const Good = 1,
Excellent = 2,
Wow = 3;
const remarks = [
[{name: Good}],
[{name: Good}, {name:Excellent}],
[{name: Good}, {name:Excellent}, {name:Wow}],
[{name: Good}, {name:Excellent}, {name:Wow}],
[{name:Excellent}],
[{name:Excellent}]
];
/*
[{name: Good, count: 4} {name: Excellent, count: 5}, {name:Wow, count:2}]
*/
function counts(remarks) {
return remarks.flat().reduce((acc, v) => {
const name = v.name;
let count = acc[name] || 0;
return {
...acc,
[name]: count + 1
}
}, {});
}
function view(counts) {
return Object.keys(counts).map(key => {
let count = counts[key];
return { name: key, count };
})
}
console.log(view(counts(remarks)));
Any time you are making a smaller set of data, or transforming data, in JavaScript reduce should be the first method you attempt to use. In this case, you may want to pair it with an indexer (hence preloading with an array of index and an array of result).
This works in one pass without needing to know the name values up front.
const remarks = [
[{name: "Good"}],
[{name: "Good"}, {name: "Excellent"}],
[{name: "Good"}, {name: "Excellent"}, {name: "Wow"}],
[{name: "Good"}, {name: "Excellent"}, {name: "Wow"}],
[{name: "Excellent"}],
[{name: "Excellent"}]
];
const stats = remarks.reduce((p,c) => (
c.forEach( ({name}) => {
if(!p[0].hasOwnProperty(name)){
p[1].push({name:name,count:0});
p[0][name] = p[1].length - 1;
}
p[1][p[0][name]].count++;
}),p),[{},[]])[1];
console.log(stats);
A slightly more concise and definitely less readable approach (but it's worth to mention) could be:
const remarks = [
[{ name: "Good" }],
[{ name: "Good" }, { name: "Excellent" }],
[{ name: "Good" }, { name: "Excellent" }, { name: "Wow" }],
[{ name: "Good" }, { name: "Excellent" }, { name: "Wow" }],
[{ name: "Excellent" }],
[{ name: "Excellent" }]
];
const stats = Object.entries(
remarks
.flat()
.reduce((acc, {name}) => (acc[name] = -~acc[name], acc), {})))
).map(([name, count]) => ({ name, count }));
console.log(stats);
It uses the comma operator in the reducer to returns the accumulator; and the bitwise operator NOT to create a counter without the needs to initialize the object upfront with all the names.
const flattenedRemarks = _.flatten(remarks);
const groupedRemarks = _.groupBy(flattenedRemarks, (remark) => remark.name);
const remarkCounts = _.mapValues(groupedRemarks, (group) => group.length);
const data = {
"mchale": {
"classes":["ESJ030", "SCI339"], // get the length
"faculty":["Hardy", "Vikrum"] // get the length
},
"lawerence":{
"classes":["ENG001"], // get the length
"faculty":["Speedman", "Lee", "Lazenhower"] // get the length
}
};
const count = Object.keys(data).map(campusName => {
const campus = data[campusName];
return Object.keys(campus).map(key => campus[key].length).reduce((p, c) => p + c, 0);
}).reduce((p, c) => p + c, 0);
console.log(count);

How to get a single array with no-repeated items, with the sum of their value(s). ordered desc

If I have the following Array:
var myArray = [
{sa67g:{id:'sa67g', name: 'Leo', value: 50}},
{sa86w:{id:'sa86w', name: 'Amy', value: 40}},
{sa33p:{id:'sa33p', name: 'Alex', value: 30}},
{sa74x:{id:'sa74x', name: 'John', value: 20}},
{sa67g:{id:'sa67g', name: 'Leo', value: 10}},
{sa33p:{id:'sa33p', name: 'Alex', value: 15}},
]
What is the best one to get a single array with no-repeated items, with the sum of their value(s) and ordered by descending value for all the repeated items from another array using lodash?
Te expected result should be something like this:
result = [{sa67g:{id:'sa67g', name: 'Leo', value: 60}},
{sa33p:{id:'sa33p', name: 'Alex', value: 45}},
{sa86w:{id:'sa86w', name: 'Amy', value: 40}},
{sa74x:{id:'sa74x', name: 'John', value: 20}}
]
I'm sure there are a bunch of ways to do it. Off the top of my head, I would use reduce to convert your array of objects into one object with summed values. Using chain to combine with some other lodash methods for ordering and transforming, it would look like this:
const result = _.chain(myArray)
.map(person => _.values(person))
.flatten()
.reduce((summed, person) => {
if (!summed[person.id]) {
summed[person.id] = person
} else {
summed[person.id].value += person.value
}
return summed
}, {})
.values()
.orderBy(['value'], ['desc'])
.map(person => ({ [person.id]: person }))
.value()
You can use lodash's _.mergeWith() to combine all objects into a single object. Since _.mergeWith is recursive, the inner properties will be merged as well, and we can use this to sum the value property. Afterwards, we convert the object back to an array using _.map():
const myArray = [{"sa67g":{"id":"sa67g","name":"Leo","value":50}},{"sa86w":{"id":"sa86w","name":"Amy","value":40}},{"sa33p":{"id":"sa33p","name":"Alex","value":30}},{"sa74x":{"id":"sa74x","name":"John","value":20}},{"sa67g":{"id":"sa67g","name":"Leo","value":10}},{"sa33p":{"id":"sa33p","name":"Alex","value":15}}];
const result = _.map(
// merge all objects into a single object, and sum the value property
_.mergeWith({}, ...myArray, (objValue = 0, srcValue = 0, key) => key === 'value' ? objValue + srcValue : undefined),
// split back into an array of objects
(v, k) => ({ [k]: v })
)
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
Easiest way to filter out single values would be to use a Set. Use it to get a set of unique keys.
Create the desired object by iterating the keys and calculating the sums.
Using native methods and assuming es8 support:
var myArray = [
{sa67g:{id:'sa67g', name: 'Leo', value: 50}},
{sa86w:{id:'sa86w', name: 'Amy', value: 40}},
{sa33p:{id:'sa33p', name: 'Alex', value: 30}},
{sa74x:{id:'sa74x', name: 'John', value: 20}},
{sa67g:{id:'sa67g', name: 'Leo', value: 10}},
{sa33p:{id:'sa33p', name: 'Alex', value: 15}},
]
var tmp = myArray.map(o => Object.values(o)[0])
.reduce((a, c) => {
const obj = a[c.name]
if (obj) {
obj.id = c.id > obj.id ? c.id : obj.id;// set highest id
obj.value += c.value; //increment vlues
} else {
a[c.name] = Object.assign({},c);
}
return a;
}, {});
var res = Object.values(tmp)
.sort((a, b) => b.value - a.value)
.map(o => ({[o.id]:o }))
console.log(res)
.as-console-wrapper { max-height: 100%!important;}
You could take a step by step approach and take the resutl for the next function with a pipe.
var array = [{ sa67g: { id: 'sa67g', name: 'Leo', value: 50 } }, { sa86w: { id: 'sa86w', name: 'Amy', value: 40 } }, { sa33p: { id: 'sa33p', name: 'Alex', value: 30 } }, { sa74x: { id: 'sa74x', name: 'John', value: 20 } }, { sa67g: { id: 'sa67g', name: 'Leo', value: 10 } }, { sa33p: { id: 'sa33p', name: 'Alex', value: 15 } }],
pipe = (...fn) => arg => fn.reduce((x, f) => f(x), arg),
objects = array => array.map(o => Object.assign({}, Object.values(o)[0])),
sum = array => array.reduce((m, o) => {
if (m.has(o.id)) {
m.get(o.id).value += o.value;
} else {
m.set(o.id, o);
}
return m;
}, new Map),
values = map => Array.from(map.values()),
sort = array => array.sort((a, b) => b.value - a.value),
map = array => array.map(o => ({ [o.id]: o })),
path = pipe(objects, sum, values, sort, map),
result = path(array);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Object properties should never be a value (ie, a key or id) – to create a key-value association, use a Map instead.
const concat = ({ id: id1, name: name1, value: v1 }, { id: id2, name: name2, value: v2 }) =>
({ id: id1, name: name1, value: v1 + v2 })
const main = xs =>
xs.map (x => Object.entries (x) [ 0 ])
.reduce ((acc, [ key, value ]) =>
acc.has (key)
? acc.set (key, concat (value, acc.get (key)))
: acc.set (key, value), new Map)
const myArray =
[ {sa67g:{id:'sa67g', name: 'Leo', value: 50}}
, {sa86w:{id:'sa86w', name: 'Amy', value: 40}}
, {sa33p:{id:'sa33p', name: 'Alex', value: 30}}
, {sa74x:{id:'sa74x', name: 'John', value: 20}}
, {sa67g:{id:'sa67g', name: 'Leo', value: 10}}
, {sa33p:{id:'sa33p', name: 'Alex', value: 15}}
]
console.log (main (myArray))
// => Map {
// 'sa67g' => { id: 'sa67g', name: 'Leo', value: 60 },
// 'sa86w' => { id: 'sa86w', name: 'Amy', value: 40 },
// 'sa33p' => { id: 'sa33p', name: 'Alex', value: 45 },
// 'sa74x' => { id: 'sa74x', name: 'John', value: 20 } }
If you want to convert the Map back to an object, you can use this
const mapToObject = m =>
Array.from(m.entries ()).reduce ((acc, [ k, v ]) =>
Object.assign (acc, { [ k ]: v }), {})

consolidating values in a list of objects based on an attribute which is the same

Bit of background, this comes from a submitted form that I used serializeArray() on
I have a list of objects like so.
[
{name: 0, value: 'waffles'},
{name: 0, value: 'pancakes'},
{name: 0, value: 'french toast'},
{name: 1, value: 'pancakes'}
]
I want to take all things that have the same name attribute and put them together. EG,
[
{name: 0, value: ['waffles', 'pancakes', 'french toast']},
{name: 1, value: ['pancakes']}
]
how would one go about this? All the things I've tried only result in one answer being shown for each name key.
This should do it:
var newlist = _.map(_.groupBy(oldlist, "name"), function(v, n) {
return {name: n, values: _.pluck(v, "value")};
});
Here's the best I could come up with:
http://jsfiddle.net/Z6bdB/
var arr = [
{name: 0, value: 'waffles'},
{name: 0, value: 'pancakes'},
{name: 0, value: 'french toast'},
{name: 1, value: 'pancakes'}
]
var obj1 = {};
$.each(arr, function(idx, item) {
if (obj1[item.name]) {
obj1[item.name].push(item.value);
} else {
obj1[item.name] = [item.value];
}
});
var result = [];
for(var prop in obj1) {
result.push({
name: prop,
value: obj1[prop]
});
}
console.log(result);
This seems to work:
var output = _.chain(input)
.groupBy(function(x){ return x.name; })
.map(function(g, k) { return { name: k, value: _.pluck(g, 'value') }; })
.value();
Demonstration
I am one of those guys that uses native functions:
var food = [
{name: 0, value: 'waffles'},
{name: 0, value: 'pancakes'},
{name: 0, value: 'french toast'},
{name: 1, value: 'pancakes'}
];
var result = food.reduce(function(res,dish){
if (!res.some(function(d){return d.name === dish.name })){
var values = food.filter(function(d){ return d.name === dish.name }).map(function(d){ return d.value; });
res.push({name: dish.name, value : values});
}
return res;
}, []);
console.log(result);
I'd probably do something like this:
function them_into_groups(m, h) {
m[h.name] || (m[h.name] = [ ]);
m[h.name].push(h.value);
return m;
}
function them_back_to_objects(v, k) {
return {
name: +k,
value: v
};
}
var output = _(input).chain()
.reduce(them_into_groups, { })
.map(them_back_to_objects)
.value();
Using _.chain and _.value makes things flow nicely and using named functions make things less messy and clarifies the logic.
Demo: http://jsfiddle.net/ambiguous/G7qwM/2/

Categories