How to count object's number in array? - javascript

There is a function which create the same objects (with different values of ID, task and point) and push it to array Box. And i want to get each number of object, and show it to user on page. 1,2,3,4,5,6.... How to do it?
box: [{
id: shortid.generate(),
task: action.task,
point: false
}]

I believe you want to add sequence number to each of your object:
const result = [{
id: '2s3wf4',
task: 'task1',
point: false
}].map((x, i) => ({
...x,
serialNumber: i + 1
}));
console.log(result)

Related

Filter array of objects whose specific properties contains a value

I'm trying to find the cleanest way to implement a filter to an array of objects depending on a string keyword. I need to return those objects whose only specific properties contains the string value.
Let's say I have the following array of objects:
const products = [
{
name: 'car',
price: 100,
image: 'someurl'
email: 'car#car.car'
available: true,
},
{
name: 'phone',
price: 200,
image: 'someurl'
email: 'phone#phone.phone'
available: false,
},
{
name: 'bottle',
price: 300,
image: 'someurl'
email: 'bottle#bottle.bottle'
available: true,
},
];
As mentioned here: Filter array of objects whose any properties contains a value
One of the cleanest way to match any value in an array of objects whose properties have different types would be:
function filterByValue(array, string) {
return array.filter(o =>
Object.keys(o).some(k => String(o[k]).toLowerCase().includes(string.toLowerCase())));
}
This filterByValue function will return those objects whose any properties match the string value.
However, I'd like to add some conditions, so it only iterates and look for some match at "name", "price" and "email" properties, not looking at "image" and "available" properties.
Make an array of the properties to look at, and look at them instead of using Object.keys.
const propsToCheck = ['name', 'price', 'email'];
function filterByValue(array, string) {
return array.filter(o =>
propsToCheck.some(k => String(o[k]).toLowerCase().includes(string.toLowerCase())
)
);
}

Return true if an array within an array contains specific key

I have the following the object:
items: [
{
object_a {
id: "1",
value: "somevalue1"
}
},
{
object_b {
id: "2"
value: "somevalue2"
items:[
{
nested_object_a {
id: "3"
value: "somevalue3"
},
nested_object_b {
id: "4"
value: "somevalue4"
},
}
]
}
},
]
I can check if the value key exists in the initial items array:
items.some(item => item.hasOwnProperty("value"));
To see if the value key exists in the nested object_b item array I can do the following:
items[1].object_b.items.some(item => item.hasOwnProperty("value"));
Instead of specifying which number in the array to look in I need to make the final expression dynamic. I'm certain I need to do a find or a filter on the top level items, but I've had no luck with it so far.
I found that using an every function on the items allowed me to return the boolean value I required form the array. The problem this created is any array item that didn't have the object_b key on was returning null and breaking my app. It turns out I needed to use an optional chaining operator to get around this (.?).
Thanks to #ikhvjs for linking that stackedoverflow article.
Working code:
items.every(item => {
item.object_b?.items.some(item => item.hasOwnProperty("value"));
});

How to retrieve certain properties of an array of objects and put it into a new array of objects? [duplicate]

This question already has answers here:
Filter array of objects based on another array in javascript
(10 answers)
Closed 2 years ago.
i have an array of objects like below,
data: [
{
name: 'name1',
id: '1',
description: 'name 1 description',
},
{
name: 'name2',
id: '2',
description: 'name 2 description',
},
{
name: 'name3',
id: '3',
description: 'name 3 description',
},
]
i have an array consisting of ids like so
const id_list = ['1','2'];
Now i want to retrieve the id and name from data array object whose id matches with id_list
so the expected output is
const new = [
{
id: '1',
name: 'name1',
},
{
id: '2',
name: 'name2',
}
]
i am new to using react, javascript or typescript. could someone help me solve this. thanks.
what i have tried?
i know that to filter the value based on one value
so if i have to filter based on one id say '1'
i can do
const new = data.filter((item) => id === item.id);
but in my case i want to filter all items which match the id_list array and should retrieve only matching object name and id and put it to a array.
You can use the map function with a find method to map every id of id_list to the corresponding object in data
const result = id_list.map((id) => data.find((d) => d.id === id));
After that you have all objects that were found by ids in result. You can either only use the props you want or map again and get only the required properties.
const final = result.map(({ id, name })=> ({ id, name }))

office-ui-fabric / fluent-ui Grouped DetailsList

Today I tried to use the Grouped DetailsList of the fluent-ui.
What I expected: I need to declare some groups, let's say red, blue, green and then just add to each item, I want to add to the List, a specific property, that maps the Item to the groups.
e.g.:
groups: [
{ key: 'red', name: 'Color: "red"'},
{ key: 'green', name: 'Color: "green"'},
{ key: 'blue', name: 'Color: "blue"' },
],
items: [...,
{ key: 'red',anyProp1: "abc", anyProp2: "dfg",...},
...,
]
What I found out I have to do: I need to sort the Array, which contains my items in that way, that all Items belonging to the Group red need to be in one block. e.g.: [red, red, red, blue, blue, green, green, green]. Now I needed to provide the information about startIndex and count to map my Array of items to the groups.
This is what a definition of a group could look like:
groups: [
{ key: 'groupred0', name: 'Color: "red"', startIndex: 0, count: 2, level: 0 },
{ key: 'groupgreen2', name: 'Color: "green"', startIndex: 2, count: 0, level: 0 },
{ key: 'groupblue2', name: 'Color: "blue"', startIndex: 2, count: 3, level: 0 },
],
I can't understand why they have done it this way (For me it's very inconvenient this way). So, while I'm more between a beginner and an intermediate in JS. I think the guys who implemented this are professionals. There must be a reason. Maybe it has something todo with performance? I could imagine that when it comes to very large lists, it performs better this way, but I'm not sure.
Does anybody knows some details about this and can explain?
Faced the same issue and got a clue here. Then bult my solution.
Following is the function to generate groups array from the given items list sorted by the grouping column:
function groupsGenerator(itemsList, fieldName) {
// Array of group objects
const groupObjArr =[]
// Get the group names from the items list
const groupNames = [...new Set(itemsList.map(item => item[fieldName]))]
// Iterate through each group name to build proper group object
groupNames.forEach(gn => {
// Count group items
const groupLength = itemsList.filter(item => item[fieldName] === gn).length
// Find the first group index
const groupIndex = itemsList.map(item => item[fieldName]).indexOf(gn)
// Generate a group object
groupObjArr.push({
key: gn, name: gn, level: 0, count: groupLength, startIndex: groupIndex
})
})
// The final groups array returned
return groupObjArr
}
Typed and with empty group name option variant of the Timus's answer
function generateGroups(items: any[], fieldName: string, emptyGroupName: string = '-'): IGroup[] {
const groups: IGroup[] = []
const groupNames = [...new Set<string>(items.map(item => item[fieldName]))]
groupNames.forEach(name => {
const groupItemsCount = items.filter(item => item[fieldName] === name).length
const groupStartIndex = items.map(item => item[fieldName]).indexOf(name)
groups.push({
key: name,
level: 0,
name: name ?? emptyGroupName,
count: groupItemsCount,
startIndex: groupStartIndex
})
})
return groups
}

Distinct Values using Set

I have been using
<FormGroup>
<Campaign
campaignName={this.campaignName.bind(this)}
campaignOptions={[...new Set(this.props.records.map(options => options.campaign))]}/>
</FormGroup>
to get a unique array for a dropdown option, however I now need to pass an array with each object in it having a label and a value.
I have refactored the code as follows,
<FormGroup>
<Campaign
campaignName={this.campaignName.bind(this)}
campaignOptions={[...new Set(this.props.records.map(options => {
return {value: options.campaign, label: options.campaign };
}))]}/>
</FormGroup>
...but the unique element is now not working (see below with duplicates). What am I doing wrong please?
The input array looks like...
[
1. 0:{_id: "zWTiLEjqrCKdxTvze", owner: "K7xTxu7PRDCuhFZRC", company_ID: "1", campaign: "newevent", …}
2. 1:{_id: "SkZzDMAWokFFYEycp", owner: "K7xTxu7PRDCuhFZRC", company_ID: "1", campaign: "instagramlaunch", …}
3. 2:{_id: "p4pychanC5Zw8iWAQ", owner: "K7xTxu7PRDCuhFZRC", company_ID: "1", campaign: "stuffinhere", …}
… more in here including more than 1 object with instagram launch for example
]
Original approach resulted in Array of...
0:"newevent"
1:"sheffieldevent"
2:"stuffinhere"
3:”instagramlaunch"
4:”anothertest"
5:”yetanother"
now results in...
0:{value: "newevent", label: "newevent"}
1:{value: "sheffieldevent", label: "sheffieldevent"}
2:{value: "stuffinhere", label: "stuffinhere"}
3:{value: "instagramlaunch", label: "instagramlaunch"}
4:{value: "instagramlaunch", label: "instagramlaunch"}
5:{value: "instagramlaunch", label: "instagramlaunch”}
6:{value: "anothertest", label: "anothertest”}
7:{value: "yetanother", label: "yetanother"}
new Set(this.props.records.map(options => {
return {value: options.campaign, label: options.campaign };
}))
Does not work, because every new object is a unique object and Set works with all types. As result, you get all options, but not unique options.
If you have the same pattern as you want, you could render the set after collecting all values and build a new objects array out of the set.
var optionsSet = new Set(array.map(option => option.campaign)),
options = Array.from(optionsSet, v => ({ value: v, label: v }));
I resolved this using lodash...
campaignOptions={_.uniqBy(this.props.records.map((options,index) => {return { value: index, label: options.campaign }}),'label')}/>

Categories

Resources