JS add all items into one array using map [duplicate] - javascript

This question already has answers here:
From an array of objects, extract value of a property as array
(24 answers)
Closed 1 year ago.
I have an object:
[
{
"id": 10,
"name": "comedy"
},
{
"id": 12,
"name": "documentary"
},
{
"id": 11,
"name": "scifi"
}
]
I need to take only the id values and add them into 1 array like so:
[ 10, 12, 13 ]
or
{ 10, 12, 13 }
I am trying:
const getIDs = value.map( ( { id } ) => ( {
id: id
} ) );
But it creates:
[
{
"id": 10
},
{
"id": 12
},
{
"id": 11
}
]

Inside the map just return the id values instead of objects
Here is the quick solution
const values = [
{
"id": 10,
"name": "comedy"
},
{
"id": 12,
"name": "documentary"
},
{
"id": 11,
"name": "scifi"
}
]
const getIDs = values.map(({id}) => id);
console.log(getIDs)

Related

How can I return an array of values from an array of grouped objects in js?

I have an array of subscriptions group by the type (basic,medium ...)
`
[
[
"Basic",
[
{ "id": 2, "name": "Basic", "started_at": "2022-01-24", "count": 4 },
{ "id": 2, "name": "Basic", "started_at": "2022-03-16", "count": 2 },
{ "id": 2, "name": "Basic", "started_at": "2022-05-16", "count": 1 }
]
],
[
"Medium",
[
{ "id": 3, "name": "Medium", "started_at": "2022-02-21", "count": 1 },
{ "id": 3, "name": "Medium", "started_at": "2022-05-28", "count": 1 }
]
],
[
"Premium",
[{ "id": 4, "name": "Premium", "started_at": "2022-04-21", "count": 1 }]
],
[
"Master",
[
{ "id": 7, "name": "Master", "started_at": "2022-07-28", "count": 1 },
{ "id": 7, "name": "Master", "started_at": "2022-08-02", "count": 1 }
]
],
[
"Jedi",
[{ "id": 6, "name": "Jedi", "started_at": "2022-09-28", "count": 1 }]
]
]
`
What I want to do is return an array containing objects foreach sub with the following data(get the count value by month):
`
[
{
label: "Basic",
data: [4, 0, 2, 0, 1,0],
},
{
label: "Medium",
data: [0, 1, 0, 0, 1,0],
},
...
]
`
The data field should contain the count field foreach subscription corresponding to the month. For example for with count 4 in January and count 2 in March it will return [4,0,1] with 0 for February.
How can I achieve that ?
I did this but it's returning only the existing month values so there is no way to know which month that value is for.
subscriptions.map((item) => {
return {
label: item[0],
data: item[1].map((value, index) => {
return value.count;
}),
};
})
You could reduce the array and create a mapper object which maps each plan with month specifc count. Something like this:
{
"Basic": {
"1": 4,
"3": 2,
"5": 1
},
"Medium": {
"2": 1,
"5": 1
},
...
}
Then loop through the entries of the object and create objects with plan as label and an array of length: 12 and get the data for that specific month using the index
const input=[["Basic",[{id:2,name:"Basic",started_at:"2022-01-24",count:4},{id:2,name:"Basic",started_at:"2022-03-16",count:2},{id:2,name:"Basic",started_at:"2022-05-16",count:1}]],["Medium",[{id:3,name:"Medium",started_at:"2022-02-21",count:1},{id:3,name:"Medium",started_at:"2022-05-28",count:1}]],["Premium",[{id:4,name:"Premium",started_at:"2022-04-21",count:1}]],["Master",[{id:7,name:"Master",started_at:"2022-07-28",count:1},{id:7,name:"Master",started_at:"2022-08-02",count:1}]],["Jedi",[{id:6,name:"Jedi",started_at:"2022-09-28",count:1}]]];
const mapper = input.reduce((acc, [plan, subscriptions]) => {
acc[plan] ??= {}
for(const { started_at, count } of subscriptions)
acc[plan][+started_at.slice(5,7)] = count
return acc;
}, {})
const output =
Object.entries(mapper)
.map( ([label, subData]) => ({
label,
data: Array.from({ length: 12 }, (_, i) => subData[i+1] ?? 0)
}) )
console.log(output)
Note:
This assumes that the data is for a single year only. If it can be across years you'd have to create another level of nesting:
{
"Basic": {
"2022": {
"1": 3
}
}
}
started_at.slice(5,7) is used to get the month number. If the dates are not in the ISO 8601 format, you can use new Date(started_at).getMonth() + 1 to get the month part.

Sort array of objects by the length of a field using lodash [duplicate]

This question already has answers here:
How to sort an array based on the length of each element?
(12 answers)
Closed 1 year ago.
I have an array like below, and I need to sort the array by the string length of name field.
for an example,
[
{
"_id": 10,
"name": "AAAAAA"
},
{
"_id": 11,
"name": "AA"
},
{
"_id": 12,
"name": "AAAA"
},
{
"_id": 13,
"name": "A"
},
{
"_id": 14,
"name": "AAAAAAAA"
}
]
I need the array like this,
[
{
"_id": 13,
"name": "A"
},
{
"_id": 11,
"name": "AA"
},
{
"_id": 12,
"name": "AAAA"
},
{
"_id": 10,
"name": "AAAAAA"
},
{
"_id": 14,
"name": "AAAAAAAA"
}
]
can any one help me out with this. Thanks.
This can be accomplished with the _.orderBy method:
_.orderBy(data, [({ name }) => name.length, 'name'], ['desc']);
Here is a break-down:
I threw some "B"s into the mix to show the secondary sorting (after length is compared). Sorting the length alone is not unique enough.
const data = [
{ "_id": 1, "name": "AAAAAA" },
{ "_id": 2, "name": "AA" },
{ "_id": 3, "name": "AAAA" },
{ "_id": 4, "name": "A" },
{ "_id": 5, "name": "AAAAAAAA" },
{ "_id": 6, "name": "BBBBBB" },
{ "_id": 7, "name": "BB" },
{ "_id": 8, "name": "BBBB" },
{ "_id": 9, "name": "B" },
{ "_id": 10, "name": "BBBBBBBB" }
];
const sorted = _.orderBy(
data, // Data to be sorted
[
({ name: { length } }) => length, // First, sort by length
'name' // Them sort lexicographically
], [
'desc', // Length (descending)
'asc' // This is implied, and could be removed
]
);
console.log(sorted);
.as-console-wrapper { top: 0; max-height: 100% !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

I have an array of object like this [duplicate]

This question already has answers here:
Group objects by property in javascript
(8 answers)
Closed 2 years ago.
let attributeSet = [{
"id": 1,
"value": 11
},
{
"id" : 1,
"value": 12
},
{
"id" : 1,
"value" : 13
},
{
"id": "2",
"value" : "Qwerty"
}
]
I want to combine all the value in values like this
attributeSet = [
{
"id": 1,
"value": [11, 12, 13]
},
{
"id": 2,
"value": "Qwerty"
}
]
I am using two for loops for comparing the ids and then pushing it into an array. Can someone suggest me any better way.
You can use reduce & inside callback check if the accumulator object have the key same as id of the object under iteration. If not then create the key and push value to it
let attributeSet = [{
"id": 1,
"value": 11
},
{
"id": 1,
"value": 12
},
{
"id": 1,
"value": 13
},
{
"id": "2",
"value": "Qwerty"
}
]
let newData = attributeSet.reduce((acc, curr) => {
if (!acc[curr.id]) {
acc[curr.id] = {
id: curr.id,
value: []
}
}
acc[curr.id].value.push(curr.value)
return acc;
}, {});
console.log(Object.values(newData))

Javascript sort object array by recent date to oldest date? [duplicate]

This question already has answers here:
How to sort an object array by date property?
(25 answers)
Closed 2 years ago.
I want to create an object array that contains all the dates from each object sorted in order from the most recent date to the oldest date.
How can I loop through the dates for each object and sort them?
Will medList[0].data.sort work? I want to sort it like this:
var newArray = [{"dose": 10, "date": "2/15/2020"}, {"dose": 20, "date": "1/18/2020"}, {"dose": 20, "date": "12/21/2019"}]
const medList = [
{
"name": "Insulin",
"dose unit": "mg",
"freq": "daily",
"route": "PO",
"data": [
{
"dose": 20,
"date": "12/21/2019"
},
{
"dose": 10,
"date": "2/15/2020"
}, {
"dose": 20,
"date": "1/18/2020"
}
]
},
{
// Another med...
} ..
]
You could do something like the following.
const medList = [{
"name": "Insulin",
"data": [{
"dose": 20,
"date": "12/21/2019"
},
{
"dose": 10,
"date": "2/15/2020"
}, {
"dose": 20,
"date": "1/18/2020"
}
]
},
{
"name": "Viagra",
"data": [{
"dose": 20,
"date": "9/9/2019"
},
{
"dose": 10,
"date": "12/15/2020"
}, {
"dose": 20,
"date": "1/22/2020"
}
]
},
]
const sortedViagra = medList[1].data.sort((a, b) => new Date(b.date) - new Date(a.date));
const sortedMeds = medList.map(med => {
return med.data.sort((a, b) => new Date(b.date) - new Date(a.date));
});
console.log('sortedMeds --->', sortedMeds)
console.log('sortedViagra -->', sortedViagra)

Need to match object values from one array to the object values from another array

In the following code. I am trying to get the id of a variant that matches the selected objects
const selected = [ { "id": 14 }, { "id": 95 } ]
const variants = [
{
"id": 1,
"option_values": [ { "id": 7 }, { "id": 95, } ]
},
{
"id": 2,
"option_values": [ { "id": 8 }, { "id": 95, } ]
},
{
"id": 3,
"option_values": [ { "id": 14 }, { "id": 95, } ]
}
]
function filterVaiant() {
return variants.filter( options => {
// return id 3 because it matches the selected objects
});
}
console.log(filterVaiant());
The filter function should return variant id:3 because it has the same option values as the selected option values.
follow up
const colors = require('colors');
const selected = [ { "id": 14 }, { "id": 95 }, { "id": 21 } ]
let selected_ids = selected.map(e=>e.id);
const variants = [
{
"id": 1,
"option_values": [ { "id": 7 }, { "id": 95, } ]
},
{
"id": 2,
"option_values": [ { "id": 8 }, { "id": 95, } ]
},
{
"id": 3,
"option_values": [ { "id": 14 }, { "id": 95, } ]
},
{
"id": 4,
"option_values": [ { "id": 14 }, { "id": 95, }, { "id": 21 } ]
}
]
let vID = variants.filter(e=> e.option_values.every(e=> selected_ids.indexOf(e.id) > -1));
console.log("answer:",vID) // Returns 3 and 4 but should only return 4
in this scenario vID is 3 and 4 but should only return 4 because it is the only one that matches the selections exactly.
You can use .filter and .every to achieve this like
const selected = [ { "id": 14 }, { "id": 95 } ];
var ids = selected.map(e=>e.id);
const variants = [
{
"id": 1,
"option_values": [ { "id": 7 }, { "id": 95, } ]
},
{
"id": 2,
"option_values": [ { "id": 8 }, { "id": 95, } ]
},
{
"id": 3,
"option_values": [ { "id": 14 }, { "id": 95, } ]
}
];
var o = variants.filter(e=> e.option_values.every(e=> ids.indexOf(e.id) > -1));
console.log(o)
What's happening here is, get all the selected ids in an array, then filter the variants array based on if every entry of option_values has all the entries as the selected ids.
For each object, check that all items in selected appear in option_values (ops alias) by checking that the length is equal, and using Array.every(), and Array.find():
const selected = [ { "id": 14 }, { "id": 95 } ]
const variants = [{"id":1,"option_values":[{"id":7},{"id":95}]},{"id":2,"option_values":[{"id":8},{"id":95}]},{"id":3,"option_values":[{"id":14},{"id":95}]}];
function filterVaiant() {
return variants.filter(({ option_values: ops }) => {
if (selected.length !== ops.length) return false;
return selected.every(({ id }) =>
ops.find((o) => id === o.id));
});
}
console.log(filterVaiant());
Using a Set to store the selected Id's to look up and Array#every in a filter
const selected = [ { "id": 14 }, { "id": 95 } ]
const variants = [
{
"id": 1,
"option_values": [ { "id": 7 }, { "id": 95, } ]
},
{
"id": 2,
"option_values": [ { "id": 8 }, { "id": 95, } ]
},
{
"id": 3,
"option_values": [ { "id": 14 }, { "id": 95, } ]
}
]
function filterVaiant(selected) {
let ids = new Set(selected.map(({id})=>id))
return variants.filter( o => o.option_values.every(({id})=>ids.has(id)));
}
console.log(filterVaiant(selected));
Another solution with map only indexof and join:
const selected = [ { "id": 14 }, { "id": 95 } ]
const variants = [
{
"id": 1,
"option_values": [ { "id": 7 }, { "id": 95, } ]
},
{
"id": 2,
"option_values": [ { "id": 8 }, { "id": 95, } ]
},
{
"id": 3,
"option_values": [ { "id": 14 }, { "id": 95, } ]
}
]
function filterVaiant(selected) {
return variants[variants.map(obj => obj.option_values).map(outterarray => outterarray.map(innerArray=>innerArray.id).join('-') ).indexOf(selected.map(eb=>eb.id).join('-'))];
}
console.log(filterVaiant(selected));

Categories

Resources