Reputation: 539
Id like to loop over an array of objects which is of unknown length and (some) unknown content and create a new set of enumerated arrays.
I know that the array has a consistent set of key:value pairs, which I'd like to use a reference to chunk out the array.
Here's the example array:
[{something:test,value:10},{something:example,value:20},{something:test,value:30}]
The function should recognize the key 'something' and create a number of arrays based on the variations of the corresponding value, so for example, in this case 2 arrays would result with an object form:
{
test: [{something:test,value:10},{something:test,value:30},
example: [{something:example,value:20}]
}
In other words I need to chunk an array based on some items value in the array, rather than size / length.
I have considered / tried using index on values etc to get size parameter, but this seems a like a huge undertaking, and I'm sure there's a faster solution.
Lodash etc do not seem to have something like this in their library.
Upvotes: 0
Views: 45
Reputation: 1
Object.Keys will allow you to grab all the keys out of each object. Since some of the content is unknown, then its impossible to know whether all objects have some linking property, like the something prop in your example.
I suppose I'd need another example, with the unknown / variant content. Because it seems like you could loop through the content detect your prop of interest. If you don't know the prop ahead of time and are doing it based on the most common prop, then the Object.keys functions should help you out. I think it would be something like this.
function enumArrays(arrayObjects){
let enumArrays = {}
let keyCounts = {}
// look at each object and get a count of the keys
for (let obj of arrayObjects){
const keys = Object.Keys(obj);
for (let key of keys){
if (keyCounts.hasOwnProperty(key)){
keyCounts[key] += 1;
} else {
keyCounts[key] = 1;
}
}
}
//determine which key to use, there are plenty of ways to do this, but ill go with a basic approach
let max = 0 // assuming positive integer counts only
let selectedKey = "";
for (let keyCount of Object.keys(keyCounts)){
if (keyCounts[keyCount] > max){
max = keyCounts[keyCount];
selectedKey = keyCount
}
}
//we now have our most common key in selected key! We can chunk the original array of Objects by that key
enumArrays['null'] = [] // its possible that some objects will not have the selected key, so we'll store those objects in a null bucket
for (let obj of arrayObjects){
if (obj[selectedKey]){
//check if prop type has been added yet
let propType = obj[selectedKey];
if (!enumArrays.hasOwnProperty(propType)){
//add an empty array to that propType
enumArrays[propType] = []
}
enumArrays[propType].push(obj)
} else {
enumArrays['null'].push(obj)
}
}
return enumArrays
}
Upvotes: 0
Reputation: 12218
You can use Array.reduce() and push the objects into arrays.
const arr = [{something:'test',value:10},{something:'example',value:20},{something:'test',value:30}]
const result = arr.reduce((acc,cur) => {
if(!Object.keys(acc).some(key => key === cur.something)){
acc[cur.something] = [cur]
}else{
acc[cur.something].push(cur)
}
return acc
},{})
console.log(result)
Upvotes: 0
Reputation: 3126
Sounds like a pretty simple reduce. Something like:
const input = [{something:"test",value:10},{something:"example",value:20},{something:"test",value:30}];
const output = input.reduce((a, c) => {
if (!Array.isArray(a[c.something])) {
a[c.something] = [];
}
a[c.something].push(c);
return a;
}, {});
console.log(output);
Upvotes: 0
Reputation: 5308
You can reduce
it:
var data=[{something:'test',value:10},{something:'example',value:20},{something:'test',value:30}];
var result = data.reduce((acc, {something, ...rest})=>{
acc[something] = acc[something] || [];
acc[something].push({something, ...rest});
return acc;
},{});
console.log(result);
Upvotes: 1