React js time conversion in time dropdown - javascript

I need to display below options in material UI dropdown
from 5 to 60 dropdown should display 5m,10m,15m,20m,,and so on and for 720 and 1440 it should display 12h and 24h
I am using below code to set state in react
` let timeoption = "5,10,15,20,25,30,40,45,60,720,1440";
setTimeOption(timeoption.split(',').map(option => {
return {
id: option,
label: `${option}m`
}
}));`
for 720,1440 label should display in "h" instead of "m"
let timeoption = "5,10,15,20,25,30,40,45,60,720,1440"; setTimeOption(timeoption.split(',').map(option => { return { id: option, label: ${option}m } }));

You can use a ternary operator in label to assign m or h based on the time value.
let timeoption = "5,10,15,20,25,30,40,45,60,720,1440";
setTimeOption(timeoption.split(',').map(option => ({
id: option,
label: `${option}${option <= 60 ? 'm' : 'h'}`
})));
this is the output produced:
[
{ id: '5', label: '5m' },
{ id: '10', label: '10m' },
{ id: '15', label: '15m' },
{ id: '20', label: '20m' },
{ id: '25', label: '25m' },
{ id: '30', label: '30m' },
{ id: '40', label: '40m' },
{ id: '45', label: '45m' },
{ id: '60', label: '60m' },
{ id: '720', label: '720h' },
{ id: '1440', label: '1440h' }
]

Related

Looping array of object into array of object javascript

so i have two arrays of object like this:
var lab =[
{ label: '1', value: 42 },
{ label: '2', value: 55 },
{ label: '3', value: 51 },
{ label: '4', value: 22 }
];
var val = [ { label: '1', value: 42 },
{ label: '2', value: 55 },
];
lab.forEach(labs=>{
val.forEach(vals=>{
labs["columns"]=vals.value
})
})
console.log(lab)
i try to get the value like this
[ { label: '1', value: 42, columns: {42,55} },
{ label: '2', value: 55, columns:{42,55} },
{ label: '3', value: 51, columns: {42,55} },
{ label: '4', value: 22, columns: {42,55} } ]
but after i ran the code i get the value that i am not wanted like this:
[ { label: '1', value: 42, columns: 55 },
{ label: '2', value: 55, columns: 55 },
{ label: '3', value: 51, columns: 55 },
{ label: '4', value: 22, columns: 55 } ]
where do i did wrong actually on the loop..
Does this do what you want?
const lab = [
{ label: '1', value: 42 },
{ label: '2', value: 55 },
{ label: '3', value: 51 },
{ label: '4', value: 22 },
];
const val = [
{ label: '1', value: 42 },
{ label: '2', value: 55 },
];
// we get an array of stuff that the OP wants to add,
// as apparently it is identical for each object.
const columns = val.map(obj => obj.value);
const a = lab.map(labs => {
return {
// shallow copys for every item.
...labs,
columns: [...columns],
};
});
console.log({ a });
.as-console-wrapper { min-height: 100%!important; top: 0; }
map array method takes a function returns a new array where each element was updated by calling that function with element as it's argument.
This answer uses two calls of map, same amount as your answer, however in your answer map calls are nested, so the inner map would be called for each element, while it's result will be always the same, in my answer we call it once.
i have figured it out by using map function
var lab =[
{ label: '1', value: 42 },
{ label: '2', value: 55 },
{ label: '3', value: 51 },
{ label: '4', value: 22 }
];
var val = [ { label: '1', value: 10 },
{ label: '2', value: 55 },
];
const a = lab.map((labs)=>{
let ab={
label:labs.label,
value:labs.value,
columns:val.map((vals)=>{
return vals.value
})
}
return ab
})
console.log(a)
hope it will help

How do I create an array of objects with a nested array based on a similar key?

I have an array that looks something like this
const example = [
{ id: '1', name: 'Person 1', organization: { id: '11', name: 'Organization A' } },
{ id: '2', name: 'Person 2', organization: { id: '12', name: 'Organization A' } },
{ id: '3', name: 'Person 3', organization: { id: '13', name: 'Organization B' } },
];
As you can see, the organization name is something I want to key off of and create a data structure like this:
const output = [
// data.value will be their ID
{
organizationName: 'Organization A',
data: [
{ label: 'Person 1', value: '1' },
{ label: 'Person 2', value: '2' },
],
},
{
organizationName: 'Organization B',
data: [
{ label: 'Person 3', value: '3' },
],
},
]
What I've tried
I know I want to use reduce for something like this, but I feel like I'm off:
const providerOptions = externalPeople.data.reduce((acc, currentValue) => {
const {
organization: { name: organizationName },
} = currentValue;
if (organizationName) {
acc.push({ organization: organizationName, data: [] });
} else {
const { name: externalPersonName, id } = currentValue;
acc[acc.length - 1].data.push({ name: externalPersonName, value: id });
}
return acc;
}, [] as any);
However the output comes out to something like this:
[
{organizationName: 'Organization A', data: []},
{organizationName: 'Organization A', data: []},
{organizationName: 'Organization B', data: []},
];
data doesn't seem to get anything pushed inside the array in this reduce function, and the organization name get duplicated... what am I doing wrong?
Easiest way is to use an Map/Set/or object to keep track of orgs you create. This way you are not searching in the array to see if the organization was found already. After you are done, you can create the array you want from the object.
const externalPeople = {
data : [
{ id: '1', name: 'Person 1', organization: { id: '11', name: 'Organization A' } },
{ id: '2', name: 'Person 2', organization: { id: '12', name: 'Organization A' } },
{ id: '3', name: 'Person 3', organization: { id: '13', name: 'Organization B' } },
],
};
const providerOptions = Object.values(externalPeople.data.reduce((acc, currentValue) => {
const {
organization: { name: organizationName },
name: externalPersonName,
id
} = currentValue;
// Is the org new? Yes, create an entry for it
if (!acc[organizationName]) {
acc[organizationName] = { organization: organizationName, data: [] };
}
// push the person to the organization
acc[organizationName].data.push({ name: externalPersonName, value: id });
return acc;
}, {}));
console.log(providerOptions)
Here is another solution
const example = [
{ id: '1', name: 'Person 1', organization: { id: '11', name: 'Organization A' } },
{ id: '2', name: 'Person 2', organization: { id: '12', name: 'Organization A' } },
{ id: '3', name: 'Person 3', organization: { id: '13', name: 'Organization B' } },
];
const result = example.reduce((res, entry) => {
const recordIndex = res.findIndex(rec => rec.organizationName === entry.organization.name);
if(recordIndex >= 0) {
res[recordIndex].data.push({ label: entry.name, value: entry.id});
} else {
const record = {
organizationName: entry.organization.name,
data: [{ label: entry.name, value: entry.id }]
};
res.push(record);
}
return res;
}, []);
console.log(result);
You are not checking if the value is already present in your accumulation acc
You can check it with a simple find in the if statement since it's an array
const providerOptions = externalPeople.data.reduce((acc, currentValue) => {
const {
organization: { name: organizationName },
} = currentValue;
//Check if organization is not present already
if (!acc.find(a => a.organization === organizationName)) {
//Add also the data of the element your are processing
acc.push({ organization: organizationName, data: [{label: currentValue.name, value: currentValue.id}] });
} else {
const { name: externalPersonName, id } = currentValue;
acc[acc.length - 1].data.push({ label: externalPersonName, value: id });
}
return acc;
}, [] as any);
I also added the data of the first element of the group you create when adding the organization.
The result should be as your expected output:
[
{
organization: 'Organization A',
data: [
{ label: 'Person 1', value: '1' },
{ label: 'Person 2', value: '2' }
]
},
{
organization: 'Organization B',
data: [
{ label: 'Person 3', value: '3' }
]
}
]
Hope it helps!
Compare this solution (using Lodash) with other solutions. Which one emphasises your intentions at most? This is why we use Lodash in our company - to maintain code as declarative as we can, because code readability, with minimum cognitive overload, is most important goal during coding.
const persons = [
{ id: '1', name: 'Person 1', organization: { id: '11', name: 'Organization A' } },
{ id: '2', name: 'Person 2', organization: { id: '12', name: 'Organization A' } },
{ id: '3', name: 'Person 3', organization: { id: '13', name: 'Organization B' } },
];
const personsByOrganizations = _.groupBy(persons, 'organization.name')
const output = _.map(personsByOrganizations, (persons, organizationName) => ({
organizationName,
data: _.map(persons, ({ name, id }) => ({
label: name,
value: id
}))
}))
Something like that with using a Set?
result = [...new Set(example.map(d => d.organization.name))].map(label => {
return {
organizationName: label,
data: example.filter(d => d.organization.name === label).map(d => {
return {label: d.name, value: d.id}
})
}
})
`

Returning array object by filtering it's nested size variants

I have the list of products that i want to filter by their varriants.size
Staring point, data I'm receiving:
const t1 = [
{
name: 'Product 1',
variants: [
{ size: 'sm', sku: '1' },
{ size: 'md', sku: '2' },
],
},
{
name: 'Product 2',
variants: [{ size: 'lg', sku: '4' }],
},
{
name: 'Product 3',
variants: [
{ size: 'sm', sku: '5' },
{ size: 'lg', sku: '6' },
],
},
{
name: 'Product 4',
variants: [{ size: 'sm', sku: '7' }],
},
]
By using ['sm', 'md'] I want to filter above object and return this result
End goal / expected results
const arr = [
{
name: 'Product 2',
variants: [{ size: 'lg', sku: '4' }],
},
{
name: 'Product 3',
variants: [{ size: 'lg', sku: '6' }],
},
]
What I've tried so far but not getting full data / missing properties.
const filter = ['sm', 'md']
const arr = t1.map((e) => {
const filter = e.variants.filter((f) => {
return filter.includes(f.size)
})
return filter
})
But only getting varriants object, rest of the data is missing.
This screenshot is bad example, this one is only filtering ['sm'] but in this case I have multiple filter option ['sm', 'md']
const
t1 = [
{ name: 'Product 1', variants: [{ size: 'sm', sku: '1' }, { size: 'md', sku: '2' }] },
{ name: 'Product 2', variants: [{ size: 'lg', sku: '4' }] },
{ name: 'Product 3', variants: [{ size: 'sm', sku: '5' }, { size: 'lg', sku: '6' }] },
{ name: 'Product 4', variants: [{ size: 'sm', sku: '7' }] }
],
filter = ['sm', 'md'];
const arr = t1
// filter t1 elements variants
.map(e => ({
...e,
variants: e.variants.filter(({ size }) => !filter.includes(size))
}))
// filter resulting elements with no variants left
.filter(({ variants }) => variants.length);
console.log(arr);
Filter each variants subarray by whether the size you want is included, then filter the whole t1 array by whether the subarray contains items.
const t1 = [
{
name: 'Product 1',
variants: [
{ size: 'sm', sku: '1' },
{ size: 'md', sku: '2' },
],
},
{
name: 'Product 2',
variants: [{ size: 'lg', sku: '4' }],
},
{
name: 'Product 3',
variants: [
{ size: 'sm', sku: '5' },
{ size: 'lg', sku: '6' },
],
},
{
name: 'Product 4',
variants: [{ size: 'sm', sku: '7' }],
},
];
const filterBy = ['sm', 'md'];
for (const obj of t1) {
obj.variants = obj.variants.filter(
subobj => !filterBy.includes(subobj.size)
);
}
const filteredInput = t1.filter(obj => obj.variants.length);
console.log(filteredInput);

Restructure an array with lodash by leveraging _.map and ._groupBy

I am looking to restructure an array of objects with lodash.
I've been trying to adapt the many examples found online without any luck. It seems I would have to use a combination of _.map and ._groupBy but I can't really wrap my head around this.
Any help is appreciated!
Initial array:
const entries = [
{
year: '2019',
children: [
{ name: 'red', amount: 1, label: 'color' },
{ name: 'yellow', amount: 20, label: 'color' },
{ name: 'green', amount: 12, label: 'color' },
],
},
{
year: '2020',
children: [
{ name: 'red', amount: 1, label: 'color' },
{ name: 'yellow', amount: 3, label: 'color' },
],
},
]
Restructured array:
[
{
id: 'red',
data: [
{ year: '2019', amount: 1 },
{ year: '2020', amount: 1 },
],
},
{
id: 'yellow',
data: [
{ year: '2019', amount: 20 },
{ year: '2020', amount: 3 },
],
},
{
id: 'green',
data: [
{ year: '2019', amount: 12 },
],
},
]
You could chain the whole operations with flatMap, groupBy and mapping.
const entries = [{ year: '2019', children: [{ name: 'red', amount: 1, label: 'color' }, { name: 'yellow', amount: 20, label: 'color' }, { name: 'green', amount: 12, label: 'color' }] }, { year: '2020', children: [{ name: 'red', amount: 1, label: 'color' }, { name: 'yellow', amount: 3, label: 'color' }] }],
result = _(entries)
.flatMap(({ year, children }) => _.map(children, ({ name: id, amount }) => ({ year, id, amount })))
.groupBy('id')
.map((data, id) => ({ id, data: _.map(data, ({ year, amount }) => ({ year, amount })) }))
.value();
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
There are probably quite a few different ways of doing this, however, I find the best approach is:
Flatten the children to one array.
Use _.groupBy to create a map of these entries keyed on name.
Use _.entries to get an array of keys and values for the map.
Finally use _.map to transform these entries into our desired output.
const entries = [
{
year: '2019',
children: [
{ name: 'red', amount: 1, label: 'color' },
{ name: 'yellow', amount: 20, label: 'color' },
{ name: 'green', amount: 12, label: 'color' },
],
},
{
year: '2020',
children: [
{ name: 'red', amount: 1, label: 'color' },
{ name: 'yellow', amount: 3, label: 'color' },
],
},
]
// Step 1
let flattenedChildren = _.flatMap(entries, e => e.children.map(c => { return { ...c, year: e.year } }));
// Step 2
let entryMap = _.groupBy(flattenedChildren , "name");
// Step 3
let mapEntries = _.entries(entryMap);
// Step 4
let result = _.map(mapEntries , ([id, items]) => { return { id, data: items.map(item => _.pick(item, ["amount", "year"]))} });
console.log("Result:", result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

How to group array

I am trying to group similar objects with the same label.
At the moment, this is the the JSON I receive.
const sizes = [{
id: [{
value: '2496',
label: 'XS'
}, {
value: '2499',
label: 'S'
}],
type: 'First Size'
}, {
id: [{
value: '2863',
label: 34
}, {
value: '2866',
label: 36
}],
type: 'Shoe Sizes'
}, {
id: [{
value: '3561',
label: 'XS'
}, {
value: '3563',
label: 'S'
}, {
value: '3565',
label: 'L'
}, , {
value: '3567',
label: 'XL'
}]
}, {
id: [{
value: '3523',
label: 34
}, {
value: '2866',
label: 36
}],
type: 'Shoe Sizes'
}]
The result I am trying to achieve is
const sizes = [{
id: [{
value: '2496,3561',
label: 'XS'
}, {
value: '2499,3563',
label: 'S'
}],
type: 'First Size'
}, {
id: [{
value: '2863,3523',
label: 34
}, {
value: '2866',
label: 36
}],
type: 'Shoe Sizes'
}, {
id: [{
value: '3565',
label: 'L'
}, , {
value: '3567',
label: 'XL'
}]
}, {
id: [{
value: '2866',
label: 37
}],
type: 'Shoe Sizes'
}]
I have tried to achieve this with underscore, but I am only able to group it by just one label, and I need to group it by any kind of label, whether it be XS or 36.
I have tried with reduce below, it is close but I just need to remove the brackets around the value, and turn the value into a string.
EX: value: '2493, 2343'
var group_to_values = sizes.reduce(function (obj, item) {
obj[item.label] = obj[item.label] || [];
obj[item.label].push(item.value);
return obj;
}, {});
var groups = Object.keys(group_to_values).map(function (key) {
return {label: key, value: group_to_values[key]};
});
You could take a hash table for same labels and iterate the outer array and the inner array. If a label is not found, it generates a new entry for the result set.
var sizes = [{ id: [{ value: '2496', label: 'XS' }, { value: '2499', label: 'S' }], type: 'First Size' }, { id: [{ value: '2863', label: 34 }, { value: '2866', label: 36 }], type: 'Shoe Sizes' }, { id: [{ value: '3561', label: 'XS' }, { value: '3563', label: 'S' }, { value: '3565', label: 'L' }, { value: '3567', label: 'XL' }] }, { id: [{ value: '3523', label: 34 }, { value: '2866', label: 36 }], type: 'Shoe Sizes' }],
labels = Object.create(null),
joined = sizes.reduce((r, a) => {
var temp;
a.id.forEach(o => {
if (labels[o.label]) {
labels[o.label].value += ',' + o.value;
return;
}
if (!temp) {
temp = Object.assign({}, a, { id: [] });
r.push(temp);
}
temp.id.push(labels[o.label] = o);
});
return r;
}, []);
console.log(joined);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Here you are, the code below would output Array called result, which is data set you desired, the loop is clear so I think it won't be an issue for you to go through it:
const sizes = [{
id: [{
value: '2496',
label: 'XS'
}, {
value: '2499',
label: 'S'
}],
type: 'First Size'
}, {
id: [{
value: '2863',
label: 34
}, {
value: '2866',
label: 36
}],
type: 'Shoe Sizes'
}, {
id: [{
value: '3561',
label: 'XS'
}, {
value: '3563',
label: 'S'
}, {
value: '3565',
label: 'L'
}, {
value: '3567',
label: 'XL'
}]
}, {
id: [{
value: '3523',
label: 34
}, {
value: '2866',
label: 36
}],
type: 'Shoe Sizes'
}]
var groupedSizes = {};
for (var current, i=0;i < sizes.length ;i++){
for (var j=0;j < sizes[i]['id'].length;j++) {
current = sizes[i]['id'][j]
if (groupedSizes[current['label']] !== undefined) {
groupedSizes[current['label']].push(current['value'])
} else {
groupedSizes[current['label']] = [current['value']]
}
}
}
var result = []
for (var key in groupedSizes) {
result.push({'id': groupedSizes[key].join(','), 'label': key})
}
console.log(result)

Categories