Reactjs: How to get values from array of objects - javascript

I am a beginner in rectjs. In my project, there is a list of objects stored in "groupedItems", and using sort() to order them and stored them into a variable "numAscending".
Now its structure is in the above picture. but I want to change them like in the below picture.
Here is the code which I tried.
groupedItems.map((items)=>{
numAscending = [...items].sort((a, b) => a.subsolution_name - b.subsolution_name);
temp.push({numAscending})
})
console.log("temp", temp)
// result = temp.map((option, key) => {
// console.log("eeeeeeee", option)
// option.map((item)=>{
// console.log("iteee", item)
// })
// });
// console.log('result', result);
I tried to fix it but failed (lines are started with //). Please give me a suggestion to solve this problem.

You probably could flatten the groupedItems array's element values, which appear to be arrays, and then sort the overall result array.
Example:
const result = groupedItems
.flat(Number.POSITIVE_INFINITY)
.sort((a, b) => a.subsolution_name - b.subsolution_name);

You can reduce it to get the array and then sort it
const reducedItems = groupedItems.reduce((prev,curr)=>{
return [...prev,...curr.numAscending]
},[]);
const sortedItems = reducedItems.sort((a, b) => a.subsolution_name - b.subsolution_name);

Related

How to sort the nested object data in react-native

{
"lion":{
"age_in_years":"10",
"name":"king",
"country":"africa"
},
"elephant":{
"age_in_years":"15",
"name":"hero",
"country":"usa"
},
"racoon":{
"age_in_years":"5",
"name":"thanos",
"country":"syria"
},
}
This is the data I'm getting through a web socket in react-native. I want to sort it in ascending order based on the "age_in_years". So the oldest animal's data should be shown at top and the youngest data at the last.
You sould better work with an array insted of object as below, first map it into array and parse the age_in_years and sort it.
const obj2Array = Object.entries(<YourObject>).map(([key, value]) => ({...value, _id: key, age_in_years: parseInt(value.age_in_years)}));
const sorted = obj2Array.sort((a, b) => a.age_in_years - b.age_in_years);
Then you can use .reduce if you want the object back, nevertheless you can use the sorted array to render it.
Sort by age in years oldest first
// use slice() to copy the array
var byAge = array.slice(0);
byAge.sort(function(a,b) {
return a.age_in_years - b.age_in_years ;
});
Store the values in array and make a sort function.
const numbers = [info.lion.age_in_years, info.elephant.age_in_years, info.racoon.age_in_years];
const ascNumbers = numbers.sort((a,b) => a-b);
If you need descending make it like this:
const descNumbers = numbers.sort((a,b) => b-a);

Filter array for every 3rd element

I'm having trouble to create an array based on a dataset, I want to filter just some elements of it by choosing one element every 3. Could you help me with this?
This is what I did.
var example = dataset.map(function(d){return d.values
.filter(function(d,i){return (i+1)%3===0;})});
the dataset log: {name:"example1", values: Array(46)}
After applying the new array looks like this. And I'm looking for this [219, 2301, 239.....373]
Thanks
Currently, you're trying to run your filter on every item in the array since you're doing it within an iteration of Array.prototype.map. You should filter the array for every third item first, and then run map on the resulting array to avoid mapping values that will end up being null.
const data = [...]
const dataSet = data
.filter((_, i) => i % 3 === 0)
.map(x => x.value)
You could also do it with a single use of Array.prototype.reduce and doing both filter and map in the same iteration like so:
const data = [...]
const dataSet = data.reduce((acc, curr, i) => {
if (i % 3 === 0) acc.push(curr.value)
return acc
}, [])

is it possible to sort an array and just get the return of the placements NOT change the order

I have an array of numbers
counter[7,3,9,5,1]
if i do counter.sort() it will change the array to
counter[1,3,5,7,9]
is it possible to sort an array and just get the return of the placements NOT CHANGE THE ORDER
something like this
sortedArrayByPlacment[3,1,4,2,0];
You can copy the array, sort it, then turn it into an object (for quick lookup) and map the original array onto the object to identify the new indicies.
You'll also need to pass a comparator function; .sort without any arguments will sort lexicographically, resulting in, eg, 11 coming before 2, which almost certainly isn't desirable.
const arr = [7,3,9,5,1];
const indexByNum = Object.fromEntries(
[...arr]
.sort((a, b) => a - b)
.map((num, i) => [num, i])
);
const indicies = arr.map(num => indexByNum[num]);
console.log(indicies);
I'm using Object.fromEntries to make the mapping less computationally complex, but you could do without it if you wanted:
const arr = [7,3,9,5,1];
const sorted = [...arr].sort((a, b) => a - b);
const indicies = arr.map(num => sorted.indexOf(num));
console.log(indicies);
PS: These snippets work only if the values are unique in the array

remove duplicates from array in moment js

i have
let array = [moment('2019-01-17'),moment('2019-01-19'),moment('2019-01-19'),moment('2019-01-21')];
i need to remove duplicates
so i written filter but it is not working correctly
array= array.filter((v,i) => !moment(array.indexOf(v)).isSame(moment(i)))
working live plunker code inside index.html
You were on the right track, but details were a bit off. Please try this:
const comparisonValues = array.map(v => v.valueOf());
array = array.filter((v,i) => comparisonValues.indexOf(v.valueOf()) == i);
Explanation:
array.filter((value, index, self) => self.indexOf(value) == index) is an useful pattern for finding unique values in an array
The intuition behind the pattern is to "pick only first instances of a value in an array"
It only works for values that can be directly compared - indexOf uses strict equality check internally (===)
momentValue.valueOf() will return an useful value for this comparison, namely number of milliseconds since the Unix Epoch
Our solution uses a helper array that consists of the millisecond values from valueOf and in filter, makes comparisons using valueOf() of the current value in iteration
Another way, if you want to use isSame, could be like this:
array = array.filter((v, i) => {
return array.findIndex(candidate => v.isSame(candidate)) == i
});
You can achieve the same result and faster with just a single Array.reduce and once you got the items grouped just get them via Object.values. This would be faster than for each items searching the entire array every time. For small arrays it would not matter but for larger it would be quite noticeable.
Here is the concise version:
let data = [moment('2019-01-17'), moment('2019-01-19'), moment('2019-01-19'), moment('2019-01-19'), moment('2019-01-19'), moment('2019-01-21')];
const result = data.reduce((a, c) => (a[c.format()] = c, a), {})
console.log(Object.values(result))
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
And here the detailed one:
let data = [moment('2019-01-17'), moment('2019-01-19'), moment('2019-01-19'), moment('2019-01-19'), moment('2019-01-19'), moment('2019-01-21')];
const result = data.reduce((accumulator, current) => {
accumulator[current.format()] = current
return accumulator
}, {})
console.log(Object.values(result))
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>

Sorting multiple array objects with different keys

Before, I was combining 2 arrays into one array and using sort(), I was able to sort them by created_at.
let result = [...item.messages, ...item.chat_messages]
result.sort((a, b) => new Date(b.created_at) - new Date(a.created_at))
item.messages = result
Now, I am in another scenario. I want to add one more array (sms_messages) into this array and however want it to order by its scheduled_at field.
Is it possible to achieve it with this approach?
let result = [...item.messages, ...item.chat_messages, ...item.sms_messages]
// and order by messages' and chat_messages' created_at (like above) together as
// sms_messages' sheduled_at
You could use || to get the first of both properties it finds to be there, assuming that each object has at least one of both properties, but scheduled_at gets precedence:
result.sort((a, b) =>
new Date(b.scheduled_at || b.created_at) - new Date(a.scheduled_at || a.created_at))
Just check which which property exists and use it to sort the objects.
const sortByDate = props => {
return (a, b) => {
let propA = props.find(p => a.hasOwnProperty(p));
let propB = props.find(p => b.hasOwnProperty(p));
if(!propA || !propB) return 0;
return new Date(b[propB]) - new Date(a[propA]);
};
}
result.sort(sortByDate(['scheduled_at', 'created_at']));

Categories