Sort an array of objects by property AND alphabetically - javascript

I understand how to sort an an array of objects by one property, but not how to re-sort the array again alphabetically (while keeping the sorting by property).
For example, I have an array:
[
{title: 'Hello', category: 'something'},
{title: 'Good', category: 'something else'},
{title: 'Monday', category: 'something'},
{title: 'Evening', category: 'something'}, {title: 'Food', category: 'others'}
]
To sort the array by category:
array.sort(
(a, b) => -b.category.localeCompare(a.category)
)
However, how can I sort the items in each category alphabetically, in this array, while keeping the elements sorted by the category?

If localeCompare returns 0, compare another field
const array = [{
title: 'Hello',
category: 'something'
},
{
title: 'Good',
category: 'something else'
},
{
title: 'Monday',
category: 'something'
},
{
title: 'Evening',
category: 'something'
}, {
title: 'Food',
category: 'others'
}
]
array.sort(
(a, b) => {
const category = -b.category.localeCompare(a.category)
if (category) return category
return a.title.localeCompare(b.title)
}
)
console.log(array)

Related

Push value to multiple arrays

const array = [{
id: 1,
name: 'test',
attrs: [{
name: 'Attribute 1',
description: 'Description 1',
}],
values: [{
name: 'value 1',
attrs: [{
name: 'Attribute 1',
type: 'Type 1',
},
{
name: 'Attribute 2',
type: 'Type 2',
},
],
}, ],
}, ];
const newArray =
array.map((item) => {
return {
...item,
isNegative: true
};
});
console.log(newArray);
I receive data as displayed in the const array. I need to push a value 'isNegative' to array[].attrs and to each values.attrs. I'm only able to do it to the array[].attrs. How can I do it to the others?
You're only mapping over the top-level array. If you need to map over the arrays within each object, that's another call to .map(). For example:
const array = [{
id: 1,
name: 'test',
attrs: [{
name: 'Attribute 1',
description: 'Description 1',
}],
values: [{
name: 'value 1',
attrs: [{
name: 'Attribute 1',
type: 'Type 1',
},
{
name: 'Attribute 2',
type: 'Type 2',
},
],
}, ],
}, ];
const newArray =
array.map((item) => {
return {
...item,
isNegative: true,
attrs: item.attrs.map((attr) => {
return {
...attr,
isNegative: true
}
})
};
});
console.log(newArray);
Same with the values property, any array within objects in values, etc. Any array that you want to map to a new structure, call .map() on it.

Get all unique items and show number of same ones in JS [duplicate]

This question already has answers here:
Group by count of objects within an array in Vanilla Javascript
(4 answers)
Closed 11 months ago.
What i mean is, imagine i have this data
const data = [
{ name: 'Apple', category: 'fruit' },
{ name: 'Orange', category: 'fruit' },
{ name: 'Banana', category: 'fruit' },
{ name: 'Milk', category: 'drink' },
{ name: 'Juice', category: 'drink' },
];
What i want is to show unique categories and show number of same items
[
{ count: 3, category: 'fruit' },
{ count: 2, category: 'drink' },
]
One Solution is leveraging JS Set to find out unique category and use it to get the count.
const data = [
{ name: 'Apple', category: 'fruit' },
{ name: 'Orange', category: 'fruit' },
{ name: 'Banana', category: 'fruit' },
{ name: 'Milk', category: 'drink' },
{ name: 'Juice', category: 'drink' },
];
const categories = new Set();
data.forEach((item) => {
categories.add(item.category);
})
const result = [];
categories.forEach((category) => {
const val = data.filter((item) => item.category === category);
result.push({count: val.length, category})
})
console.log(result);
I don't know if this is the right way to do but it should work
const data = [
{ name: 'Apple', category: 'fruit' },
{ name: 'Orange', category: 'fruit' },
{ name: 'Banana', category: 'fruit' },
{ name: 'Milk', category: 'drink' },
{ name: 'Juice', category: 'drink' },
];
function filterArray(arr) {
const map = new Map()
arr.map(i => map.set(i.category, map.get(i.category) + 1 || 1))
return [...map].map(i => ({'count': i[1],'category': i[0]}))
}
let result = filterArray(data)
console.log(result)

How to sort the array of objects in ascending order based on created date using javascript and react? [duplicate]

This question already has answers here:
How to sort an object array by date property?
(25 answers)
Closed 2 years ago.
i have data like below,
const subItems = [
{
id: '1',
title: 'subitem-one',
status: 'new',
createdAt: '2020-08-13T16:32:10.000Z',
orders: [
{
id: '1',
title: 'subitem1-order-one',
status: 'new',
},
{
id: '2',
title: 'subitem1-order-two',
status: 'new',
},
]
},
{
id: '2',
title: 'subitem-two',
status: 'new',
createdAt: '2020-08-16T12:02:06.000Z',
orders: [
{
id: '2',
title: 'subitem2-order-one',
status: 'new',
},
],
},
]
how can i sort the subItems array of objects in ascending order based on createdAt property using javascript.
expected output is as below,
const subItems = [
{
id: '1',
title: 'subitem-one',
status: 'new',
createdAt: '2020-08-16T16:32:10.000Z',
orders: [
{
id: '1',
title: 'subitem1-order-one',
status: 'new',
},
{
id: '2',
title: 'subitem1-order-two',
status: 'new',
},
]
},
{
id: '2',
title: 'subitem-two',
status: 'new',
createdAt: '2020-08-13T12:02:06.000Z',
orders: [
{
id: '2',
title: 'subitem2-order-one',
status: 'new',
},
],
},
]
how can i do sort the data in ascending order based on createdAt. the most recently created should be first. could someone help me with this. thanks.
You sĀ“can simply use the sort function with the callback:
const sortedItems = subItems.sort((a,b) => b.createdAt.localeCompare(a.createdAt))
Ascending
subItems.sort((a,b)=>new Date(a.createdAt) - new Date(b.createdAt))
Descending
subItems.sort((a,b)=>new Date(b.createdAt) - new Date(a.createdAt))
Use the Array#sort function with a callback for your sort-algorithm.
function sortSubItems(subItems) {
subItems.sort((a,b) => {
a= (new Date(a.createdAt)).getTime();
b= (new Date(b.createdAt)).getTime();
return b-a;
});
return subItems;
}
const subItems = [
{
id: '1',
title: 'subitem-one',
status: 'new',
createdAt: '2020-08-13T16:32:10.000Z',
orders: [
{
id: '1',
title: 'subitem1-order-one',
status: 'new',
},
{
id: '2',
title: 'subitem1-order-two',
status: 'new',
},
]
},
{
id: '2',
title: 'subitem-two',
status: 'new',
createdAt: '2020-08-16T12:02:06.000Z',
orders: [
{
id: '2',
title: 'subitem2-order-one',
status: 'new',
}
]
},
];
console.log(sortSubItems(subItems));

Vue merge value in nested object with parent array

If I have an array where each object has a neste object:
items: [
{
id: 1,
name: Tomato
category: {
id: 1,
name: Vegetable
}
},
{
id: 2,
name: Apple
category: {
id: 2,
name: Fruit
}
}
]
How do I get a new array with the field name of the nested object merged in the parent array?
items_extended: [
{
id: 1,
name: Tomato
category: Vegetable
},
{
id: 2,
name: Apple
category: Fruit
}
]
You can map through the array and return a modified version.
var items_extended = items.map(function (item) {
return {
id: item.id,
name: item.name,
category: item.category.name,
};
});

Filter Object out of Array with difference of matching two values

I have an array, which I want to filter with another array. My goal is to filter the array with two values and I want the result with only matching exactly this two values. This is what I have so far:
const array = [
{
title: 'Title A',
someOtherProps: [
'AAA',
]
}, {
title: 'Title B',
someOtherProps: [
'AAA',
'BBB',
]
}, {
title: 'Title C',
someOtherProps: [
'BBB',
'CCC'
]
}, {
title: 'Title D',
someOtherProps: [
'BBB',
]
}, {
title: 'Title E',
someOtherProps: [
'CCC'
]
},
]
const filter = [
'AAA',
'BBB',
]
let result = array.filter(obj => obj.someOtherProps.some(props => filter.includes(props)))
console.log(result);
So my result has Objects with my filtered value.
// My Result
{
title: 'Title A'
someOtherProps: [
'AAA',
]
}, {
title: 'Title B'
someOtherProps: [
'AAA',
'BBB',
]
}, {
title: 'Title C'
someOtherProps: [
'BBB',
'CCC'
]
}, {
title: 'Title D'
someOtherProps: [
'BBB',
]
}
So far so good. But I dont need all objects, which has one of the values. I need the object, which has exactly these two values combined.
// Wanted Result
{
title: 'Title B'
someOtherProps: [
'AAA',
'BBB',
]
}
I cant find a way. I know how to get the difference of two arrays. But I need the difference of two values, if you know what I mean.
Use Array#every() on filter array and check its all values are included in the someOtherProps of object.
You can use Array#find() for that purpose if you want only one object
const array = [ { title: 'Title A', someOtherProps: [ 'AAA', ] }, { title: 'Title B', someOtherProps: [ 'AAA', 'BBB', ] }, { title: 'Title C', someOtherProps: [ 'BBB', 'CCC' ] }, { title: 'Title D', someOtherProps: [ 'BBB', ] }, { title: 'Title E', someOtherProps: [ 'CCC' ] }, ]
const filter = ['AAA','BBB',]
let res = array.find(x => filter.every( a => x.someOtherProps.includes(a)));
console.log(res)
If you want all the elements that matches the condition then use filter().
const array = [ { title: 'Title A', someOtherProps: [ 'AAA', ] }, { title: 'Title B', someOtherProps: [ 'AAA', 'BBB', ] }, { title: 'Title C', someOtherProps: [ 'BBB', 'CCC' ] }, { title: 'Title D', someOtherProps: [ 'BBB', ] }, { title: 'Title E', someOtherProps: [ 'CCC' ] }, ]
const filter = ['AAA','BBB',]
let res = array.filter(x => filter.every( a => x.someOtherProps.includes(a)));
console.log(res)
Change with this:
array.filter(x => filter.every( a => x.someOtherProps.includes(a)));

Categories

Resources