how to sum from array of object using lodash only? - lodash

hey I want to calculate the sum of one property from array of object using lodash
suppose the array of object looks like this ...
salary":[{
"bills":[{"electricity":300,"milk":500},
{"electricity":240,"milk":200},
{"electricity":800,"milk":900}]
}]
I want to calculate the sum of 'milk' from that object using lodash.

Use nested _.sumBy() calls. The internal gets the sum of milk from one salary, and the external sums all salaries:
const data = {"salary":[{"bills":[{"electricity":300,"milk":500},{"electricity":240,"milk":200},{"electricity":800,"milk":900}]}]}
const result = _.sumBy(data.salary, ({ bills }) => _.sumBy(bills, 'milk'))
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

Something like this
const bills = salary.map((s)=> s.bills)
_(bills).map((objs,key)=>({
'milk': _.sumBy(objs, 'milk')
})).value

Related

knex json object WHERE condition

I have sql jsonb column in db named 'car' with structure
[{'brand':'audi', 'year':'2001'}] --> how to filter WHERE brand=audi?
this doesn't seem to be right:
return await db(db_table)
.select('*')
.whereRaw('car->>$.?? = ?', ['brand', 'audi']);
#felixmosh
Since your object is an array of objects, your suggested code won't work.
Try something like this:
return await db(db_table)
.select('*')
.whereRaw('car->>$[0].?? = ?', ['brand', 'audi']);
// ----------------^ this selects the first element of the array

How to delete items from an array in Vue

I have a function called updateAnswer with multiple dynamic parameters.
updateAnswer(key, answer, array = false) {
if (array) {
if(this.answers.contains.find(element => element === answer)) {
//Delete item from array if already element already exists in this.answers.contains array.
} else {
Vue.set(this.answers, key, [...this.answers.contains, answer]);
}
} else {
Vue.set(this.answers, key, answer);
}
},
I'd like to know how delete an item in the array if the value already exists in the array.
You can use method called splice:
Just reference on your array and set values in the brackets the first is referenced on the position, the second is how many datas you want to splice/delete.
The function looks like this:
this.array.splice(value, value)
Lets see on an example - you have array food= [apple, banana, strawberry] than I'm using this.food.splice(1,1)..
my array looks now like this food = [apple, strawberry] - first value in my brackets are the position, the second one is the amount of "numbers" you want to delete.
Hopefully this helps you out!
I suppose each value in this.answers.contains is unique?
Anyways, if you just want to delete the item if already exists, I suggest filter(). It should look like below:
if(this.answers.contains.find(element => element === answer)) {
this.answers.contains = this.answers.contains.filter(c => c !== answer)
}
Also, the if condition if(this.answers.contains.find(element => element === answer)) could also be replaced by if(this.answers.contains.includes(answer))
Hope that could help you.

How to sort flatlist in React Native?

I have data stored in a state that is shown in flatlist, I want to sort the data based on ratings. So if I click on sort button they should be sorted in ascending order and when I click again, they should be sorted in descending order.
I have an array of objects stored in state, below is just a piece of data that is important.
show_data_list = [{ ratings : { overall : 4, ...other stuff } } ]
Is there a way I could do it, I tried using the map function which sorts array
list.map((a,b) => a-b)
But how can I use this to sort my array of objects, I cant pass in 2 item.rating.overall as the parameter.
Thanks in advance for the help :)
You can use javascript's built in sort function. You can provide a custom comparer function for it, which should return a negative value if the first item takes precedence, 0 if they are the same and a positive value if the second value should take precedence.
show_data_list.sort((a, b) => { return a.ratings.overall - b.ratings.overall; }). This will sort the data in the ascending order.
show_data_list.sort((a, b) => { return b.ratings.overall - a.ratings.overall; }). This will sort it in the descending order.
This is how I solved it stored the data in a variable and then sorted it based on condition
let rating = this.state.show_data_list;
rating.sort(function(a,b) {
return a.ratings.Overall < b.ratings.Overall
Try This
Sort your List Ascending/ Descending order with name or other string value in list
const [productSortList, setProductSortList] = useState(productarray);
where productarray is your main array
Ascending
productarray.sort((a, b) => a.products_name < b.products_name)
Descending
productarray.sort((a, b) => b.products_name < a.products_name),
You can reset the state of array you have passed as data in Flatlist
ascending ->
setProductSortList(
productarray.sort((a, b) => a.products_name < b.products_name),
);
do same for descending

v-if inside v-for in vue.js

I am using the Vue-google-maps package to render a google map on my site with locations on it.
To display the locations with markers I am doing it like this:
<GmapMarker v-for="hotel in hotels" :key="hotel.id"
:position="hotel._geoloc"
:clickable="true"
:draggable="false"
#click="center=hotel._geoloc"
#mouseover="show = true"
#mouseleave="show = false"
>
<gmap-info-window v-if="show">
<hotel-card :hotel="hotel" :session="session"/>
</gmap-info-window>
</GmapMarker>
But for some reason(I am new to vue), it shows every info window and ignores the v-if statement. How can I fix this issue? In what way should I render it?
just like this.
hotels = []
axios.get("hotels").then( (data) => {
hotels = data
})
just ignored that axios.get its just example that data came from backend. so as you can see hotels came from the request right or in the backend so to put a show property for that first thing is to know the condition what hotel should i show or hide.
hotels = []
axios.get("hotels").then( (data) => {
if (data.slot === 0 )
data.show = true
else data.show = false
hotels = data
})
just like that. i just check if the slot is equals to zero so i will not show that hotel. just for example. something like that

Lodash choose which duplicates to reject

I have array of objects, objects have properties say "a", "b" and "c".
Now I need to filter out objects which has unique values of "a & b".
However c plays role on which objects to keep and which ones to reject.
If I do uniqBy on properties a and b, I will be blindly rejecting other objects. It will keep the first object it encounters in the array and reject all other duplicates.
Let me know if you need more clarification on the question.
This is how I found the uniq objects based on two properties.
var uniqArray= _.uniqBy(obj, function(elem) { return [elem.a, elem.b].join(); })
lodash uniq - choose which duplicate object to keep in array of objects
Do we have better solution?
Here is an example of input and expected output
Input: var arrayOfObj = [{a:1, b:1, c:2}, {a:1,b:1,c:1}, {a:2, b:2,c:2}];
Output: arrayOfObj = [{a:1,b:1,c:1}, {a:2, b:2,c:2}]; there should not be any duplicate a1,b1 combination
According to Lodash documentation, the order of result values is determined by the order they occur in the array. Therefore you need to order the array using the 'c' property in order to get the expected result.
To do so, you can use _.sortBy. It orders a collection in asc order based on a property or an iteratee. I think your problem could be solved using a property directly though you could use a function to provide a more accurate comparator if needed.
After that, you just perform the uniqBy action and retrieve the result:
var res = _(arrayOfObj)
.orderBy('c')
.uniqBy('a', 'b')
.value();
console.log(res);
Here's the fiddle.
As I read in the comments, your 'c' property is a timestamp. If you want to order from latest to newest, you can pass an iteratee to sort by in order to reverse the natural order by 'c':
var res = _(arrayOfObj)
.orderBy(function(obj) {
return -(+obj.c);
})
.uniqBy('a', 'b')
.value();
console.log(res);
You can check it out in this update of the previous fiddle. Hope it helps.
Would help to know what the actual data is and what you want to achieve with it. Here's an idea: group your objects based on a and b, then from each grouping, select one item based on c.
var arrayOfObj = [
{a:1, b:1, c:2},
{a:1, b:1, c:1},
{a:2, b:2, c:2}
];
var result = _.chain(arrayOfObj)
.groupBy(function (obj) {
return obj.a.toString() + obj.b.toString();
})
.map(function (objects) {
//replace with code to select the right item based on c
return _.head(objects);
}).value();