Group by array and add field and sub array in main array
This is a snippet I wrote for these kind of situations. You can add this functionality to all of your arrays:
Object.defineProperty(Array.prototype, 'group', {
enumerable: false,
value: function (key) {
var map = {};
this.forEach(function (e) {
var k = key(e);
map[k] = map[k] || [];
map[k].push(e);
});
return Object.keys(map).map(function (k) {
return {key: k, data: map[k]};
});
}
});
You can use it like this. You can just pass a function which defines how you want to group your data.
var newArray = arr.group(function (item) {
return item.optionName;
});
Working Fiddle
If you need, you can replace {key: k, data: map[k]}
with {Name: k, Data: map[k]}
.
This is also more compact ES6 version of the code above:
Object.defineProperty(Array.prototype, 'group', {
enumerable: false,
value: function (key) {
let map = {};
this.map(e => ({k: key(e), d: e})).forEach(e => {
map[e.k] = map[e.k] || [];
map[e.k].push(e.d);
});
return Object.keys(map).map(k => ({key: k, data: map[k]}));
}
});
Use it like this:
let newArray = arr.group(item => item.optionName))
Group array of javascript objects based on value into there own sub array of objects
You could use a closure over a hash table for the same email address and their items.
var data = [{ email: "alex@test.com", fn: "Alex", sn: "McPherson", phone: "01233xxxxx", hours: "40", rate: "20", amount: "200", vat: "60", agency: "test", start: "08/06/2017", end: "10/06/2017" }, { email: "mike@test.com", fn: "Mike", sn: "Mann", phone: "01233xxxxx", hours: "50", rate: "70", amount: "500", vat: "90", agency: "test", start: "08/06/2017", end: "10/06/2017" }, { email: "fred@test.com", fn: "Fred", sn: "Frogg", phone: "01233xxxxx", hours: "80", rate: "90", amount: "800", vat: "100", agency: "test", start: "08/06/2017", end: "10/06/2017" }, { email: "alex@test.com", fn: "Alex", sn: "McPherson", phone: "01233xxxxx", hours: "90", rate: "30", amount: "900", vat: "120", agency: "test", start: "08/06/2017", end: "10/06/2017" }], result = data.reduce(function (hash) { return function (r, o) { if (!hash[o.email]) { hash[o.email] = []; r.push(hash[o.email]); } hash[o.email].push(o) return r; }; }(Object.create(null)), []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Group rows in an associative array of associative arrays by column value and preserve the original first level keys
$arr = array();
foreach ($old_arr as $key => $item) {
$arr[$item['id']][$key] = $item;
}
ksort($arr, SORT_NUMERIC);
How to group subarrays by a column value?
There is no native one, just use a loop.
$result = array();
foreach ($data as $element) {
$result[$element['id']][] = $element;
}
How to group keys and values of an (sub)array and sum its values using PHP?
I'm surprised at all the long and complicated answers. However, the initial foreach to model your data to something manageable is needed. After that you just need to do a really simple array_walk.
<?php
$result = array();
foreach ($array as $el) {
if (!array_key_exists($el[0], $result)) {
$result[$el[0]] = array();
}
$result[$el[0]][] = $el[1];
}
array_walk($result, create_function('&$v,$k', '$v = array_sum($v) / count($v);'));
?>
Result:
Array
(
[ALFA] => 187
[BETA] => 167
[ZETA] => 254
[GAMA] => 175.5
)
Most efficient method to groupby on an array of objects
If you want to avoid external libraries, you can concisely implement a vanilla version of groupBy()
like so:
var groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
console.log(groupBy(['one', 'two', 'three'], 'length'));
// => {"3": ["one", "two"], "5": ["three"]}
Manipulate an array of objects inside another array
You can go with the following approach:
array1 =
[
{
"first": "A",
"second": [
"one"
]
},
{
"first": "A",
"second": [
"three"
]
},
{
"first": "C",
"second": [
"four"
]
},
{
"first": "D",
"second": [
"one"
]
},
{
"first": "C",
"second": [
"three"
]
},
]
var array2 = []
array1.forEach(function(item) {
var existing = array2.filter(function(v, i) {
return v.first == item.first;
});
if (existing.length) {
var existingIndex = array2.indexOf(existing[0]);
array2[existingIndex].second = array2[existingIndex].second.concat(item.second);
} else {
if (typeof item.second == 'string')
item.second = [item.second];
array2.push(item);
}
});
console.log(array2);
Group objects by multiple properties in array then sum up their values
Use Array#reduce with a helper object to group similar objects. For each object, check if the combined shape
and color
exists in the helper. If it doesn't, add to the helper using Object#assign to create a copy of the object, and push to the array. If it does, add it's values to used
and instances
.
var arr = [{"shape":"square","color":"red","used":1,"instances":1},{"shape":"square","color":"red","used":2,"instances":1},{"shape":"circle","color":"blue","used":0,"instances":0},{"shape":"square","color":"blue","used":4,"instances":4},{"shape":"circle","color":"red","used":1,"instances":1},{"shape":"circle","color":"red","used":1,"instances":0},{"shape":"square","color":"blue","used":4,"instances":5},{"shape":"square","color":"red","used":2,"instances":1}];
var helper = {};var result = arr.reduce(function(r, o) { var key = o.shape + '-' + o.color; if(!helper[key]) { helper[key] = Object.assign({}, o); // create a copy of o r.push(helper[key]); } else { helper[key].used += o.used; helper[key].instances += o.instances; }
return r;}, []);
console.log(result);
multiple grouping of documents with nested array in mongodb
You can use an aggregation query, but it will impact on performance and speed of response, there are two options, one using $unwind
and another using $accumulator
operator,
using $accumulator
:
$group
bycategory
andfield
$accumulator
to do custom JavaScript logic and merge items array, you can improve and update as per your requirement$project
to show required fields
db.collection.aggregate([
{
$group: {
_id: {
category: "$category",
field: "$field"
},
items: {
$accumulator: {
init: function() { return []; },
accumulate: function(items1, items2) {
return items1.concat(items2);
},
accumulateArgs: ["$items"],
merge: function(items1, items2) {
return items1.concat(items2);
},
finalize: function(state) {
var items = {}, finalItems = [];
state.forEach(function(item) {
if (items[item.title]) {
items[item.title].value.push(item.value);
}
else {
item.value = [item.value];
items[item.title] = item;
}
});
for (var i in items) {
finalItems.push(items[i]);
}
return finalItems;
},
lang: "js"
}
}
}
},
{
$project: {
_id: 0,
category: "$_id.category",
field: "$_id.field",
items: 1
}
}
])
using $unwind
: (not recommended)
$unwind
deconstruct theitems
array$group
bycategory
,field
anditem
title and construct the array if item values$group
bycategory
andfield
and construct theitems
array withtitle
andvalue
$project
to show required fields
db.collection.aggregate([
{ $unwind: "$items" },
{
$group: {
_id: {
category: "$category",
field: "$field",
title: "$items.title"
},
value: { $push: "$items.value" }
}
},
{
$group: {
_id: {
category: "$_id.category",
field: "$_id.field"
},
items: {
$push: {
title: "$_id.title",
value: "$value"
}
}
}
},
{
$project: {
_id: 0,
category: "$_id.category",
field: "$_id.field",
items: 1
}
}
])
Playground
Related Topics
How to Register Event with Useeffect Hooks
Access to Es6 Array Element Index Inside For-Of Loop
Converting JSON Results to a Date
Why Does Changing One Array Alters the Other
How to Set a Cookie with Expire Time
How to Create a Simple Http Proxy in Node.Js
How to Access Custom Attributes from Event Object in React
Converting 24 Hour Time to 12 Hour Time W/ Am & Pm Using JavaScript
How to Resolve Typeerror: Cannot Convert Undefined or Null to Object
How to Get the <Html> Tag HTML with JavaScript/Jquery
How to Disable Right-Click Context-Menu in JavaScript
Editing in the Chrome Debugger
Downloading Canvas Element to an Image
Pass JavaScript Variable to Flask Url_For
Can't Trigger Click with Jquery in a Chrome Extension