How to group an array of objects individually into single ones - javascript

I'm using lodash to group an array of objects:
let people = [
{name:'carl',group:'one'}, 
{name:'john',group:'one'}, 
{name:'dean',group:'three'}
]
_.groupBy(people,"group");
Result:
one: Array (2 items)
0: Object {group: "one", name: "carl"}
1: Object {group: "one", name: "john"}
three: Array (1 item)
0: Object {group: "three", name: "dean"}
What I want is the objects with group array length higher than 1 to separate into another array individually like this:
one: Array (1 item)
0: Object {group: "one", name: "carl"}
one: Array (1 item)
0: Object {group: "one", name: "john"}
three: Array (1 item)
0: Object {group: "three", name: "dean"}
What is the best way to do that?

I think you can use the method "sort"
let people = [{name:'carl',group:'one'},
{name:'john',group:'one'},
{name:'dean',group:'three'}];
people.sort(function(a,b){
return a.name.localeCompare(b.name)
});
Reference:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

Related

Can I assign a copy of an array of objects and add to those objects at the same time?

Say I have an array of objects:
const myArr = [
{name: 'one'},
{name: 'two'}
]
If I wanted to use this array of object as a base and add a custom property to the objects for each use case I might have, could I assign the array to a new variable and also change the contents of its objects at the same time?
I know this can be done in 2 steps, but I'm wondering if it's possible to do it all at once?
For example:
const copyArr = myArr;
copyArr.forEach(obj => obj.newProp = 'some-new-prop');
This would now be
[
{name: 'one', newProp: 'some-new-prop'},
{name: 'two', newProp: 'some-new-prop'}
]
You can use Array.map to iterate over each item and modify them.
Note that map will not modify your original array and therefore is immutable.
const myArr = [{ name: "one" }, { name: "two" }];
const copyArr = myArr.map((item) => ({
...item,
newProps: "some-new-prop",
}));
// [ { name: 'one', newProps: 'some-new-prop' },
// { name: 'two', newProps: 'some-new-prop' } ]

Add objects inside a nested Map function [duplicate]

This question already has answers here:
How can I group an array of objects by key?
(32 answers)
Most efficient method to groupby on an array of objects
(58 answers)
Group array items using object
(19 answers)
Closed 2 years ago.
Im building a function on Javascript to reduce an array like this:
var myArray = [
{sku: "one", price: "3"},
{sku: "two", price: "5"},
{sku: "one", price: "2"},
{sku: "three", price: "3"},
{sku: "three", price: "9"}
];
to this:
{ one: [ '3', '2' ], two: [ '5' ], three: [ '3', '9' ] }
in order to categorize my skus. It works just fine right now.
function itemQuantity(data) {
let group_to_values = data.reduce(function (obj, item) {
obj[item.sku] = obj[item.sku] || [];
obj[item.sku].push(item.price);
return obj;
}, {});
return group_to_values;
}
console.log(itemQuantity(myArray));
My issue comes when I try to modify it. instead of having one: [ '3', '2' ] I need the NUMBER of items (or quantity) {one: 2, two: 1...} I trieed to add obj.length but cant make it work!
Please help!

Deleting the exact object in array when value is false

My code looks like this:
var data = someDataWhichComesFromOtherMethod
var array = [
{name: "one", value:"data1", caption:"aaa"...},
{name: "two", value:"data2", caption:"bbb"...},
{name: "three", value:"data3", caption:"ccc"...},
{name: "four", value:"data4", caption:"ddd"...}
...
]
What I want to do is to: first check if the array is not empty and later check if incoming data is true or not and when it's not, whole object needs to be deleted from the array.
I started with:
if (array && array.length) {
//true
} else {
//false
}
For example, if data4 is null or "", array should look like this:
var array = [
{name: "one", value:"data1", caption:"aaa"...},
{name: "two", value:"data2", caption:"bbb"...},
{name: "three", value:"data3", caption:"ccc"...}
...
]
If you are trying to test the value of value and remove the item from the array when it is falsey, you could use filter to get the items that are truthy.
var array = [
{name: "one", value:"data1", caption:"aaa"},
{name: "two", value:"data2", caption:"bbb"},
{name: "three", value:"data3", caption:"ccc"},
{name: "four", value:null, caption:"ddd"},
{name: "five", value:"", caption:"eee"}
]
var result = array.filter(item => item.value)
console.log(result);

Creating new object from another object without persisting changes

I'm using an Array as a container for some basic boilerplate objects which can be copied and added to another Array and then modified. The problem is when I assign the new array ownership of the object any changes persist down to the original object (which shouldn't change).
An example:
var originals = [{ name: "One", value: 1 }, { name: "Two", value: 2 }, { name: "Three", value: 3 }];
var notOriginal = [];
notOriginal.push(originals[0]);
// THIS GIVES ME - notOriginal = [{ name: "One", value: 1 }];
notOriginal[0].name = "Uno";
// THIS RESULTS IN - originals = [{ name: "Uno", value: 1 },...];
I'm trying to keep the "originals" variable the same - it shouldn't change.
I've googled quite a bit and tried some things but not sure where to find a solution.
Specifically this is happening in VueJS whereas the object is in my data()
Make a deep copy of it using JSON.parse & JSON.stringify
var originals = [{
name: "One",
value: 1
}, {
name: "Two",
value: 2
}, {
name: "Three",
value: 3
}];
var notOriginal = [];
notOriginal.push(JSON.parse(JSON.stringify(originals[0])));
notOriginal[0].name = "Uno";
console.log(originals)
You can use Object.assign to make a copy of the object.
var originals = [{
name: "One",
value: 1
}, {
name: "Two",
value: 2
}, {
name: "Three",
value: 3
}];
var notOriginal = [];
notOriginal.push(Object.assign({}, originals[0]));
notOriginal[0].name = "Uno";
console.log(originals);
Objects are passed by reference.
In order to copy an object you can use Object.assign({}, obj) which will return a new object with the duplicated properties within obj.
var originals = [{ name: "One", value: 1 }, { name: "Two", value: 2 }, { name: "Three", value: 3 }];
var notOriginal = originals.map(obj => Object.assign({}, obj));
notOriginal[0].name = "bart";
console.log(originals[0], notOriginal[0]);
I found a solution by using jQuery.extend(true, {}, myObj); but would still like to know what this is called so I can understand this reactivity better.
Thanks

How to partition array into multiple groups using Lodash?

I'm trying to find a concise way to partition an array of objects into groups of arrays based on a predicate.
var arr = [
{id: 1, val: 'a'},
{id: 1, val: 'b'},
{id: 2, val: 'c'},
{id: 3, val: 'a'}
];
//transform to below
var partitionedById = [
[{id: 1, val: 'a'}, {id: 1, val:'b'}],
[{id: 2, val: 'c'}],
[{id: 3, val: 'a'}
];
I see this question , which gives a good overview using plain JS, but I'm wondering if there's a more concise way to do this using lodash? I see the partition function but it only splits the arrays into 2 groups (need it to be 'n' number of partitions). The groupBy groups it into an object by keys, I'm looking for the same but in an array (without keys).
Is there a simpler way to maybe nest a couple lodash functions to achieve this?
You can first group by id, which will yield an object where the keys are the different values of id and the values are an array of all array items with that id, which is basically what you want (use _.values() to get just the value arrays):
// "regular" version
var partitionedById = _.values(_.groupBy(arr, 'id'));
// chained version
var partitionedById = _(arr).groupBy('id').values().value();

Categories