Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have an array of objects -
[
{ name:'abc',
lRange: '2020-01-01',
hRange: '2020-01-22',
},
{ name:'abc',
lRange: '2020-01-01',
hRange: '2020-01-22',
},
{ name:'def',
lRange: '2020-01-15',
hRange: '2020-01-30',
},
{ name:'ghi',
lRange: '2020-02-10',
hRange: '2020-02-22',
}
]
I need to get the min Date and Max Date range combining all the dates lRange and hRange dates - there will be a overlap of the dates too.
I have tried sorting by date times but that is not giving me the correct range. any ideaS?
Here's one way to do it, though I suspect there are more elegant methods. It converts each string date into a date object and compares them. Finally it takes the min and max and converts them back into readable strings.
let dates = [{
name: 'abc',
lRange: '2019-02-01',
hRange: '2020-01-22',
},
{
name: 'abc',
lRange: '2020-01-01',
hRange: '2020-01-22',
},
{
name: 'def',
lRange: '2020-01-15',
hRange: '2020-01-30',
},
{
name: 'ghi',
lRange: '2020-02-10',
hRange: '2020-02-22',
}
]
let output = {}
dates.forEach(obj => {
if (!output.min) {
output.min = new Date(obj.lRange);
output.max = new Date(obj.hRange);
} else {
output.min = Math.min(output.min, new Date(obj.lRange))
output.max = Math.max(output.max, new Date(obj.hRange))
}
})
//convert back to date strings
output.min = new Date(output.min).toISOString().split("T")[0]
output.max = new Date(output.max).toISOString().split("T")[0]
console.log(output)
You can use flatMap to get all dates and then sort it. After sorting the first element (i.e element at index 0) is minRange and element at last index is maxRange.
const arr = [
{ name: "abc", lRange: "2020-01-01", hRange: "2020-01-22" },
{ name: "abc", lRange: "2020-01-01", hRange: "2020-01-22" },
{ name: "def", lRange: "2020-01-15", hRange: "2020-01-30" },
{ name: "ghi", lRange: "2020-02-10", hRange: "2020-02-22" },
];
const sortedResult = arr
.flatMap((obj) => [obj.lRange, obj.hRange])
.sort((a, b) => new Date(a) - new Date(b));
const result = {
min: sortedResult[0],
max: sortedResult[sortedResult.length - 1],
};
console.log(result);
You can pull the lRagnes and hRanges out into individual arrays if it makes it easier for you.
var lDates = [];
var hDates = [];
yourArray.map((innerObjects) => {
lDates .push(innerObjects.lRange);
hDates .push(innerObjects.hRange);
});
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 months ago.
Improve this question
I want to construct a JSON object from the result obtained by iterating through the array below.
Here is the array list : Input
var input = [
{
bio: "Test",
id: 2,
image: "http://localhost:8000/media/default.jpg",
user: 2
},
{
bio: "Test2",
id: 3,
image: "http://localhost:8000/media/default.png",
user: 2
}
]
I want something like the below:
Expected output:
{
"Test": {
bio: "Test",
id: 2,
image: "http://localhost:8000/media/default.jpg",
},
"TestTwo": {
bio: "TestTwo",
id: 3,
image: "http://localhost:8000/mediafile/default.jpg",
}
}
I am able to get array of objects but not the exact format that I want. Need to call ajax with the same output.
var input = [
{
bio: "Test",
id: 2,
image: "http://localhost:8000/media/default.jpg",
user: 2
},
{
bio: "Test2",
id: 3,
image: "http://localhost:8000/media/default.png",
user: 2
}
];
const final = input.reduce((res, obj) => {
res[obj.bio] = obj;
return res;
}, {});
console.log(final);
Previous answer you asked to do the opposite, and my answer was:
Use Object.values, and add user property with value 2:
const input = {
Test: {
bio: "Test",
id: 2,
image: "http://localhost:8000/media/default.jpg",
},
TestTwo: {
bio: "TestTwo",
id: 3,
image: "http://localhost:8000/mediafile/default.jpg",
},
};
const objs = Object.values(input);
for (let obj of objs) {
obj.user = 2
}
console.log(JSON.stringify(objs, null, 4))
/*
[
{
"bio": "Test",
"id": 2,
"image": "http://localhost:8000/media/default.jpg",
"user": 2
},
{
"bio": "TestTwo",
"id": 3,
"image": "http://localhost:8000/mediafile/default.jpg",
"user": 2
}
]
*/
Other ways to add property user:
You could use Use Array.prototype.map()
objs = objs.map(obj => ({ ...obj, user: 2 }))
or use with more readable with object assign
objs = objs.map(obj => {
const userPropsObj = {
user: 2
};
return Object.assign(obj, userPropsObj);
});
The answer to this question which tend to return back to the initial input(object) instead of an array:
you could iterate over the array and delete user property we add and assign each object with bio as the key.
const input = [
{
bio: "Test",
id: 2,
image: "http://localhost:8000/media/default.jpg",
user: 2
},
{
bio: "Test2",
id: 3,
image: "http://localhost:8000/media/default.png",
user: 2
}
];
const output = {};
for (let obj of input) {
delete obj.user;
output[obj.bio] = obj;
}
console.log(output)
PS: Please, Don't delete the question as you did before because you delete the answers we did too, And maybe answers help someone else!
const obj = input.reduce((result, item) => { result[item.bio] = item;
return result;
}, {});
reduce is a higher-order function it takes a method as an argument that method contains the result and items in my example; it iterates over each item in the array and assigns the whole object value to the key we created which is item.bio accumulating all these keys will results in one object with the keys and values as needed.
It might be a very basic question for people here but I have to ask away.
So I was going through reducce recently and I came through this example where I could find the maximum of some value in an array of object. Please, have a look at this code.
var pilots = [
{
id: 10,
name: "Poe Dameron",
years: 14
}, {
id: 2,
name: "Temmin 'Snap' Wexley",
years: 30
}, {
id: 41,
name: "Tallissan Lintra",
years: 16
}, {
id: 99,
name: "Ello Asty",
years: 22
}
];
If I write soemthing like this to find the maximum years,
var oldest_of_them_all = pilots.reduce(function (old, current) {
var old = (old.years > current.years) ? old.years : current.years;
return old
})
I get 22 as my value, and if I dont involve the property years, i.e-
var oldest_of_them_all = pilots.reduce(function (old, current) {
var old = (old.years > current.years) ? old : current;
return old
})
I get the object Object {id: 2, name: "Temmin 'Snap' Wexley", years: 30} as my value. Can someone explain why the first example is wrong and what is happening in there? Also, if I Just want to fetch the years value, how can I do that? Thanks in advance.
In the first example, as you are not returning the object there is no object property (years) of the accumulator (old) after the first iteration. Hence there is no year property to compare with.
var pilots = [
{
id: 10,
name: "Poe Dameron",
years: 14
}, {
id: 2,
name: "Temmin 'Snap' Wexley",
years: 30
}, {
id: 41,
name: "Tallissan Lintra",
years: 16
}, {
id: 99,
name: "Ello Asty",
years: 22
}
];
var oldest_of_them_all = pilots.reduce(function (old, current) {
console.log(old);// the value is not the object having the property years after the first iteration
var old = (old.years > current.years) ? old.years : current.years;
return old;
})
console.log(oldest_of_them_all);
So I have an array with a data of
var today = "2020-08-31"
var array = [
{
name: "Joshua",
id: 1,
date: "2020-08-31"
},
{
name: "Michael",
id: 2,
date: "2020-09-1"
}]
I want to create a sectionList that the sectionHeader title will be depending on the date today and will compare it to the date value from the array. so for example the date from the array is "2020-08-31" and today's date is same as "2020-08-31" the title should be "Today" and tomorrow is "2020-09-01" and the date from the array is still "2020-08-31" the title should be "Yesterday" is it possible?? please help me. im stuck with this. Thank you!!!!
Use the parse function from the JS Date library to parse the date hence convert it into long and then return the string (yesterday, today, tomorrow).
Add the displayDate into you array in order to loop through and display the field's value.
const today = "2020-08-31"
let array = [{
name: "Joshua",
id: 1,
date: "2020-08-31"
},
{
name: "Michael",
id: 2,
date: "2020-09-1"
}
]
array = array.map(x => ({
...x,
displayDate: (() => {
if (Date.parse(today) < Date.parse(x.date)) {
return 'yesterday';
} else if (Date.parse(today) > Date.parse(x.date)) {
return 'tomorrow';
}
return 'today';
})()
}));
console.log(array)
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have data like:
var data = [
{
items: [
{
id: 123
},
{
id: 234
},
{
id: 123
}
]
}, {
items: [
{
id: 123
},
{
id: 234
}
]
}
]
so, I want count object deep in array inside of all data by property 'id'.
ex: data.countObject('id',123) //return 3.
and my data have about xx.000 item, which solution best?
Thanks for help (sorry for my English)
You can use reduce & forEach. Inside the reduce callback you can access the items array using curr.items where acc & curr are just parameters of the call back function. Then you can use curr.items.forEach to get each object inside items array
var data = [{
items: [{
id: 123
},
{
id: 234
},
{
id: 123
}
]
}, {
items: [{
id: 123
},
{
id: 234
}
]
}];
function getCount(id) {
return data.reduce(function(acc, curr) {
// iterate through item array and check if the id is same as
// required id. If same then add 1 to the accumulator
curr.items.forEach(function(item) {
item.id === id ? acc += 1 : acc += 0;
})
return acc;
}, 0) // 0 is the accumulator, initial value is 0
}
console.log(getCount(123))
I want a function that takes an array and filters out old duplicates.
Specifically, if duplicate ids exist in myList, keep only the object with the newest date. Given the following array
let myList = [{
id: "e9519e95-5a10-4274-ac24-de72ad60ffd7",
date: "2018-02-21 21:04:13"
},
{
id: "026e7ecf-d236-4aff-b26d-7546ac85b7d5",
date: "2018-02-22 21:04:13"
},
{
id: "e9519e95-5a10-4274-ac24-de72ad60ffd7",
date: "2018-02-23 21:04:13"
}]
the function should return:
[{
id: "026e7ecf-d236-4aff-b26d-7546ac85b7d5",
date: "2018-02-22 21:04:13"
},
{
id: "e9519e95-5a10-4274-ac24-de72ad60ffd7",
date: "2018-02-23 21:04:13"
}]
You can use the function reduce to build the desired output.
let myList = [{ id: "e9519e95-5a10-4274-ac24-de72ad60ffd7", date: "2018-02-21 21:04:13"},{ id: "026e7ecf-d236-4aff-b26d-7546ac85b7d5", date: "2018-02-22 21:04:13"},{ id: "e9519e95-5a10-4274-ac24-de72ad60ffd7", date: "2018-02-23 21:04:13"}];
let result = Object.values(myList.reduce((a, {id, date}) => {
if (a[id]) {
if (a[id].date < date) a[id] = {id, date};
} else a[id] = {id, date};
return a;
}, {}));
console.log(result);
Put the entries into a hash table keyed by id. Each time you add an entry, look up the id and either keep the existing entry or replace it with the new one, based on whichever has a more recent date.
Map and Array.prototype.map() can be combined to functionally filter key based duplicates from arrays.
Array.prototype.sort() can be leveraged to guarantee order.
See below for a practical example.
// Input.
const input = [
{id: "e9519e95-5a10-4274-ac24-de72ad60ffd7", date: "2018-02-21 21:04:13"},
{id: "026e7ecf-d236-4aff-b26d-7546ac85b7d5", date: "2018-02-22 21:04:13"},
{id: "e9519e95-5a10-4274-ac24-de72ad60ffd7", date: "2018-02-23 21:04:13"}
]
// Sort By Date.
const sortDate = array => array.sort((A, B) => new Date(A.date)*1 - new Date(B.date)*1)
// Filter Duplicates.
const filter = array => [...new Map(array.map(x => [x.id, x])).values()]
// Output.
const outputRaw = filter(input) // No guaranteed order.
const outputSorted = sortDate(filter(sortDate(input))) // Guaranteed latest.
// Proof.
console.log('Raw', outputRaw)
console.log('Sorted', outputSorted)
This isn't the best answer, just another take on #Ele's solution offered for completeness. Instead of plucking the values after the unique set is found, it works on the returned array for each iteration. The find during each iteration should be less efficient than a key lookup, which is one of the reasons it's not the best answer.
let myList = [{
id: "e9519e95-5a10-4274-ac24-de72ad60ffd7",
date: "2018-02-21 21:04:13"
}, {
id: "026e7ecf-d236-4aff-b26d-7546ac85b7d5",
date: "2018-02-22 21:04:13"
}, {
id: "e9519e95-5a10-4274-ac24-de72ad60ffd7",
date: "2018-02-23 21:04:13"
}]
let result = myList.reduce((arr, { id, date }) => {
let found = arr.find(v=>v.id==id)
if (found) {
if (found.date < date)
found.date = date
}
else
arr.push({ id, date });
return arr;
}, []);
console.log(result);