I'm developing an application in React.JS
I have the array:
array =
[
{
"id": 1,
"user": {
"id": 1,
"name": "user-1"
},
"date": "2021-01-10",
"hour": {
"id": 1,
"time": "09:30:00.000"
},
"duration": {
"id": 1,
"time": 30
},
"type": {
"id": 1,
"name": "type-1"
},
"prof": {
"id": 1,
"name": "prof-1"
},
},
{
"id": 2,
"user": {
"id": 2,
"name": "user-2"
},
"date": "2021-01-14",
"hour": {
"id": 2,
"time": "10:00:00.000"
},
"duration": {
"id": 1,
"time": 45
},
"type": {
"id": 1,
"name": "type-1"
},
"prof": {
"id": 1,
"name": "prof-1"
},
}
]
and:
hour =
[
{
"id": 1,
"time": "09:30:00.000"
},
{
"id": 2,
"time": "10:00:00.000"
},
{
"id": 3,
"time": "10:30:00.000"
}
]
I need to show in a select only the hours that are not available given the equality condition in prof and day.
To try to do this I tried with
{
array.map(item => {
if (item.prof.id === "1" && item.date === "2021-01-14"){
return (
hour.map(elem => {
if (elem.id != item.hour.id){
return <option value={elem.time.id}>{elem.hour.time}</option>
}
})
);
}
})
}
In short I need to show the available hours.
For the example case, it should only show as an option: 09:30:00.000 and 10:30:00.000, as available hours.
How can I do it, suggestions?
your code works perfectly with some little changes:
1. === Operation checks type and value, in this case, prof.id has number type and not equal to string 1.
2. value and text of the options component should be elem.id and elem.time.
const OptionCreator = () => {
const profBusyHours = array
.filter((item) => item.prof.id === 1 && item.date === "2021-01-14")
.map((item) => item.hour.id);
return hour
.filter((elem) => profBusyHours.includes(elem.id) === false)
.map((elem) => (
<option key={elem.id} value={elem.id}>
{elem.time}
</option>
));
};
Related
I have an JSON file with data inside of an user
[
{
"_id": "62bd5fba34a8f1c90303055c",
"index": 0,
"email": "mcdonaldholden#xerex.com",
"nameList": [
{
"id": 0,
"name": "Wendi Mooney"
},
{
"id": 2,
"name": "Holloway Whitehead"
}
]
},
{
"_id": "62bd5fbac3e5a4fca5e85e81",
"index": 1,
"nameList": [
{
"id": 0,
"name": "Janine Barrett"
},
{
"id": 1,
"name": "Odonnell Savage"
},
{
"id": 2,
"name": "Patty Owen"
}
]
},
{
"_id": "62bd5fbaf8f417d849c135db",
"index": 2,
"email": "pattyowen#xerex.com",
"nameList": [
{
"id": 0,
"name": "Earline Goff"
},
{
"id": 1,
"name": "Glenna Lawrence"
},
{
"id": 7,
"name": "Bettye Sawyer"
}
]
I had to sort every user by : if user has more than two names
if user ids are consecutive
and if user ids are numbers
I managed to sort user by more than two names and if ids are consecutive
userData.filter(({nameList}) =>
nameList.length > 2 &&
!nameList.some(({id}, index, array) => index && array[index - 1].id !== id - 1)
);
In the case that an object has an id as number I should not return the objects. How can I implement that in my code?
The output is expected to be all the arrays that meet the filter, and some() criteria. Which is if objects has more than 2 names, its ids are consecutive and the ids should be a number.
If you want to check if the id is of type number:
(typeof id == "number")
To check if can be cast to a number
(id == parseInt(id, 10))
The complete code then (you were close):
var userData = get_data();
userData = userData.filter(function(item) {
return item.nameList.length > 2 &&
item.nameList.every(function(item, index, arr) {
return parseInt(item.id) == item.id && (index == 0 || item.id - arr[index - 1].id == 1)
})
})
console.log(userData);
function get_data() {
return [{
"_id": "62bd5fba34a8f1c90303055c",
"index": 0,
"email": "mcdonaldholden#xerex.com",
"nameList": [{
"id": 0,
"name": "Wendi Mooney"
},
{
"id": 2,
"name": "Holloway Whitehead"
}
]
},
{
"_id": "62bd5fbac3e5a4fca5e85e81",
"index": 1,
"nameList": [{
"id": 0,
"name": "Janine Barrett"
},
{
"id": 1,
"name": "Odonnell Savage"
},
{
"id": 2,
"name": "Patty Owen"
}
]
},
{
"_id": "62bd5fbaf8f417d849c135db",
"index": 2,
"email": "pattyowen#xerex.com",
"nameList": [{
"id": 0,
"name": "Earline Goff"
},
{
"id": 1,
"name": "Glenna Lawrence"
},
{
"id": 7,
"name": "Bettye Sawyer"
}
]
}
];
}
.as-console-wrapper {
max-height: 100% !important
}
I have a JSON file with data inside.
I have to filter the data by : if user has more than two names, and if user ids are consecutive.
The JSON file :
[
{
"_id": "62bd5fba34a8f1c90303055c",
"index": 0,
"email": "mcdonaldholden#xerex.com",
"nameList": [
{
"id": 0,
"name": "Wendi Mooney"
},
{
"id": 2,
"name": "Holloway Whitehead"
}
]
},
{
"_id": "62bd5fbac3e5a4fca5e85e81",
"index": 1,
"nameList": [
{
"id": 0,
"name": "Janine Barrett"
},
{
"id": 1,
"name": "Odonnell Savage"
},
{
"id": 2,
"name": "Patty Owen"
}
]
}, ...
I have managed to find an a solution to filter if the users have more than two names : userData.filter((names,i) => { return names?.nameList?.filter(names => { return names.name;}).length > 2 ; })
But I cant seem to grasp myself around the concept of filtering the consecutive ids.
Also I was advised to not use any for loops at all. Only ES6 array loops like map, forEach and filter.
Here's a solution that uses every() to compare the ID of every element with the previous ID:
const result = data.filter(({nameList}) =>
nameList.length > 2 &&
nameList.every(({id}, i, a) => !i || id === a[i - 1].id + 1)
);
Complete snippet:
const data = [{
"_id": "62bd5fba34a8f1c90303055c",
"index": 0,
"email": "mcdonaldholden#xerex.com",
"nameList": [{
"id": 0,
"name": "Wendi Mooney"
}, {
"id": 2,
"name": "Holloway Whitehead"
}]
}, {
"_id": "62bd5fbac3e5a4fca5e85e81",
"index": 1,
"nameList": [{
"id": 0,
"name": "Janine Barrett"
}, {
"id": 1,
"name": "Odonnell Savage"
}, {
"id": 2,
"name": "Patty Owen"
}]
}];
const result = data.filter(({nameList}) =>
nameList.length > 2 &&
nameList.every(({id}, i, a) => !i || id === a[i - 1].id + 1)
);
console.log(result);
I have an array of objects called orders:
const orders = [
{
"order_id": 47445,
"order_type": "Wholesale",
"items": [
{
"id": 9,
"department": "Womens",
"type": "Dress",
"quantity": 4,
"detail": {
"ID": 13363,
"On Sale": 1,
}
}
]
}
];
I need to get the quantity when both the order_type (Wholesale) and items.detail.ID (13363) match.
I have so far tried the following:
const result = orders.find(item => item.order_type == "Wholesale").items
.reduce((total, item) => {
if(item.detail.ID == 13363) {
return item.quantity;
}
}, 0);
Where result correctly returns 4
My issue, and I'm sure I am missing something very simple is that when I have multiple items in my orders array, it fails.
const orders = [
{
"order_id": 47445,
"order_type": "Wholesale",
"items": [
{
"id": 9,
"department": "Womens",
"type": "Dress",
"quantity": 4,
"detail": {
"ID": 13363,
"On Sale": 1,
}
},
{
"id": 56,
"department": "Womens",
"type": "Skirt",
"quantity": 12,
"detail": {
"ID": 76884,
"On Sale": 0,
}
},
{
"id": 89,
"department": "Mens",
"type": "Shirts",
"quantity": 20,
"detail": {
"ID": 98223,
"On Sale": 1,
}
}
]
}
];
The same
const result = orders.find(item => item.order_type == "Wholesale").items
.reduce((total, item) => {
if(item.detail.ID == 13363) {
return item.quantity;
}
}, 0);
returns undefined
Thank you
The find helper just returns the first match, so you need to use another helper like filter, like this:
const ID = 13363;
const result = orders
.filter((order) => order.order_type === 'Wholesale')
.reduce((acc, curr) => {
const items = curr.items.filter((item) => item.detail.ID === ID);
console.log(items);
// You can sum the matching items and then push them into the acc array
const quantity = items.reduce((sum, item) => (sum += item.quantity), 0);
acc.push(quantity);
return acc;
}, []);
This will return an array of matching quantities.
Not sure about the use case but here you go
const result = orders.find(item => item.order_type == "Wholesale").items
.reduce((total, item) => {
if (item.detail.ID == 13363) {
total += item.quantity;
}
return total
}, 0);
You can even create a function to make the search dynamic.
const orders = [
{
"order_id": 47445,
"order_type": "Wholesale",
"items": [
{
"id": 9,
"department": "Womens",
"type": "Dress",
"quantity": 4,
"detail": {
"ID": 13363,
"On Sale": 1,
}
},
{
"id": 56,
"department": "Womens",
"type": "Skirt",
"quantity": 12,
"detail": {
"ID": 76884,
"On Sale": 0,
}
},
{
"id": 89,
"department": "Mens",
"type": "Shirts",
"quantity": 20,
"detail": {
"ID": 98223,
"On Sale": 1,
}
}
]
}
];
findMyItem=( ID )=>{
var result = null ;
const result2 = orders.find(item => item.order_type == "Wholesale").items
.map(( item) => {
if(item.detail.ID == ID ) {
result = item.quantity;
}
}, 0);
return result ;
}
console.log( "result" ,findMyItem( 13363 ) )
console.log( "result" ,findMyItem( 98223) )
console.log( "result" ,findMyItem( 76884) )
You could use Array.find() on the orders array to find the correct order, searching for the first order that matches both the order_type and has an item matching the desired itemId (using Array.some()).
If this order exists, we can then find the corresponding item quantity using .find() again,
const orders = [ { "order_id": 47445, "order_type": "Wholesale", "items": [ { "id": 9, "department": "Womens", "type": "Dress", "quantity": 4, "detail": { "ID": 13363, "On Sale": 1, } }, { "id": 56, "department": "Womens", "type": "Skirt", "quantity": 12, "detail": { "ID": 76884, "On Sale": 0, } }, { "id": 89, "department": "Mens", "type": "Shirts", "quantity": 20, "detail": { "ID": 98223, "On Sale": 1, } } ] } ]
function findItemQuantity(orders, orderType, itemId) {
// Find the first order with the right order_type and containing the right item id
const order = orders.find(order => order.order_type = orderType && order.items.some(item => item.detail.ID === itemId));
if (!order) {
return null;
}
const item = order.items.find(item => item.detail.ID === itemId);
if (!item) {
return null;
}
return item.quantity;
}
console.log("Quantity found:", findItemQuantity(orders, 'Wholesale', 13363))
console.log("Quantity found:", findItemQuantity(orders, 'Wholesale', 76884))
const result = orders
.filter(order => order.order_type == "Wholesale")
.map(order => order.items.find(item => item.detail.ID == 13363))
.filter(item => item)
.reduce((total, { quantity }) => quantity + total, 0);
const orders = [{
"order_id": 47445,
"order_type": "Wholesale",
"items": [{
"id": 9,
"department": "Womens",
"type": "Dress",
"quantity": 4,
"detail": {
"ID": 13363,
"On Sale": 1,
}
}]
},
{
"order_id": 47445,
"order_type": "Whole",
"items": [{
"id": 9,
"department": "Womens",
"type": "Dress",
"quantity": 4,
"detail": {
"ID": 13363,
"On Sale": 1,
}
}]
}
]
const result = orders.reduce(v => {
return v.items.map(a => {
if (v.order_type == 'Wholesale' && a.detail.ID == 13363) {
return v
}
})
})
console.log(result)
const orders = [{
"order_id": 47445,
"order_type": "Wholesale",
"items": [{
"id": 9,
"department": "Womens",
"type": "Dress",
"quantity": 4,
"detail": {
"ID": 13363,
"On Sale": 1,
}
}]
}];
var result = null;
const result2 = orders.find(item => item.order_type == "Wholesale").items
.map((item) => {
if (item.detail.ID == 98223) {
result = item.quantity;
}
}, 0);
console.log("result", result)
I have array of arrays that contains obj, I should only take arrays that contain an obj with a specific key.
I tried to use a double filter but it doesn't work.
Can you give me some advice?
let result = [
[
{
"id": 1
},
{
"id": 2
}
],
[
{
"id": 3
},
{
"id": 4
},
{
"id": 5,
"type": {
"id": 1555
}
}
],
[
{
"id": 6,
"type": {
"id": 5456
}
}
]
];
const c = result.filter(array => array.filter(a => a.hasOwnProperty('type') === true));
console.log(c);
Result:
[
[
{
"id": 3
},
{
"id": 4
},
{
"id": 5,
"type": {
"id": 1555
}
}
],
[
{
"id": 6,
"type": {
"id": 5456
}
}
]
]
The filter in your filter function is wrong because you don't want to return a new collection, you want to return a boolean expression. Array.some() helps and checks if any item in that subarray has this property.
let result = [
[{
"id": 1
},
{
"id": 2
}
],
[{
"id": 3
},
{
"id": 4
},
{
"id": 5,
"type": {
"id": 1555
}
}
],
[{
"id": 6,
"type": {
"id": 5456
}
}]
];
const validArrays = result.filter(subArray => subArray.some(item => item.hasOwnProperty('type')));
console.log(validArrays);
You'll have to check whether the length of the return value from the inner array is > 0. Only if the length of the return value from the inner filter is > 0 the outer filter returns true and store it into validArrays.
let result = [[{"id":1},{"id":2}],[{"id":3},{"id":4},{"id":5,"type":{"id":1555}}],[{"id":6,"type":{"id":5456}}]];
const validArrays = result.filter(subarray => subarray.filter(item => item.hasOwnProperty('type') === true).length > 0);
console.log(validArrays);
I wrote the contents of this JSON to the array "heroes", but I don't know how to get "damage", "basicAttack.category" and "specialAttack.category" for mapping. I tried to solve this problem but unfortunately I don't know how.
{
"id": 20,
"name": "Warrior",
"skills": [
{
"id": 1,
"basicAttack": {
"id": 2,
"name": "Hit1",
"category": "weakAttack"
},
"specialAttack": {
"id": 16,
"name": "Special1",
"category": "spellAttack"
},
"damage": 200
},
{
"id": 2,
"basicAttack": {
"id": 3,
"name": "Hit2",
"category": "rangeAttack"
},
"specialAttack": {
"id": 17,
"name": "Special2",
"category": "fightAttack"
},
"damage": 100
}
]
}
and this is my way of mapping and what data I'm trying to get
const item = this.state.heroes.skills.map(item => {
/*i dont have idea how map
<p>{item.damage}</p>
<p>{item.specialAttack.cathegory} + {item.basicAttack.category}</p>
*/
})
Just map over the heroes.skills and you will find the result how to access the value
var heroes ={
"id": 20,
"name": "Warrior",
"skills": [
{
"id": 1,
"basicAttack": {
"id": 2,
"name": "Hit1",
"category": "weakAttack"
},
"specialAttack": {
"id": 16,
"name": "Special1",
"category": "spellAttack"
},
"damage": 200
},
{
"id": 2,
"basicAttack": {
"id": 3,
"name": "Hit2",
"category": "rangeAttack"
},
"specialAttack": {
"id": 17,
"name": "Special2",
"category": "fightAttack"
},
"damage": 100
}
]
}
heroes.skills.map(hero=>{
console.log("damage...........",hero.damage)
console.log("basicAttack.category.........",hero.basicAttack.category)
console.log("specialAttack.category........",hero.specialAttack.category)
})
if you want to render then you have to return it and then render
const heroesDiv = this.state.heroes.skills.map((hero) => (
<>
<p>{item.damage}</p>
<p>{item.specialAttack.category} + {item.basicAttack.category}</p>
</>
))
this.state.heroes.skills.map((item) => {
return `<div><p>${item.damage}</p><p>${item.specialAttack.category} ${item.basicAttack.category}</p></div>`
})
let data = {
"id": 20,
"name": "Warrior",
"skills": [
{
"id": 1,
"basicAttack": {
"id": 2,
"name": "Hit1",
"category": "weakAttack"
},
"specialAttack": {
"id": 16,
"name": "Special1",
"category": "spellAttack"
},
"damage": 200
},
{
"id": 2,
"basicAttack": {
"id": 3,
"name": "Hit2",
"category": "rangeAttack"
},
"specialAttack": {
"id": 17,
"name": "Special2",
"category": "fightAttack"
},
"damage": 100
}
]
}
this is how you can map
return (
<div>
{data.skills.map(item=>
<div key={item.id}>
<h3>{item.id}: {item.basicAttack.name}-{item.basicAttack.category}, {item.specialAttack.name}-{item.specialAttack.category}</h3>
</div>)}
</div>
)
const item = this.state.heroes.skills.map(item => {
return(
<React.Fragment key={item.id}>
<p>{item.damage}</p>
<p>{item.specialAttack.id}</p>
<p>{item.basicAttack.id}</p>
<p>{item.damage}</p>
<React.Fragment>
)
})
You can use JSON.parse to parse the json data and you can easily map as shown in the working snippet below.
var data='{"id":20,"name":"Warrior","skills":[{"id":1,"basicAttack":{"id":2,"name":"Hit1","category":"weakAttack"},"specialAttack":{"id":16,"name":"Special1","category":"spellAttack"},"damage":200},{"id":2,"basicAttack":{"id":3,"name":"Hit2","category":"rangeAttack"},"specialAttack":{"id":17,"name":"Special2","category":"fightAttack"},"damage":100}]}';
var jsondata=JSON.parse(data);
console.log(jsondata.skills[0].damage);
console.log(jsondata.skills[0].basicAttack['category']);
console.log(jsondata.skills[0].specialAttack['category']);
You can do it as this
const item = this.state.heroes.skills.map(item => {
return (
<React.Fragment>
<p>{item.damage}</p>
<p>{item.specialAttack.category} + {item.basicAttack.category}</p>
</React.Fragment>
);
})
Hope it helps