问题
I try to modify data in Vue for chartjs.
The basic datas are purchase orders with supplier_id
and supplier_name
I like to know, how many orders each supplier has:
methods: {
render() {
let suppliers = []
_.each(this.orders, function (value, key) {
if(!_.find(suppliers, {name: value.supplier_name})) {
suppliers.push({
name: value.supplier_name,
num: 1
});
}
else {
let supplier = _.find(suppliers, {name: value.supplier_name})
let data = {
name: value.supplier_name,
num: supplier.num + 1
}
Vue.set(suppliers, suppliers.findIndex(suppliers => suppliers.name === value.supplier_name), data)
}
})
console.log(suppliers)
}
},
I read many posts and I created the solution above. But is it the best practice to do it?
回答1:
Just to explain Dan's answer a bit as judging from the code in the original question, it might not make a lot of sense when you first look at it.
Create an empty object. This will be the "dictionary", which we will build in the next step. The idea is that we can fill this Object with keys/values for easy access. The keys will be the
supplier_name
s and the values will be how many orders eachsupplier_name
has.render() { const hash = {};
Build the dictionary. Since
this.orders
is an array, you can use forEach() to loop through its values. Take each order's supplier name (o.supplier_name
) and use it as a key to look for a value inhash
. If you find one, add1
to it and store it back to the same location inhash
. If you don't find one, store the value 1 at that location (|| 1
). Again,forEach()
will do this for each order inthis.orders
. When it finishes, you should have a complete dictionary ofsupplier_name
s along with how many orders each one has.this.orders.forEach(o => { hash[o.supplier_name] = hash[o.supplier_name] + 1 || 1; })
Transform the object "dictionary" into an array. Since hash is an Object, we can't use
forEach()
to iterate over them like we did previously. However we can get an array containing just thesupplier_name
s using Object.keys(). Then we can use map() to iterate over them and return a transformed result for each. Each result looks like this:{ name: <supplier name>, num: <number of orders> }
const suppliers = Object.keys(hash).map(name => ({ name: name, num: hash[name] })) console.log(suppliers); }
While Lodash is a great library, it's really not needed in this case. A basic understanding of the built-in functions in JavaScript goes a long way.
回答2:
You can make this simpler and without using the lodash library:
render() {
const hash = {};
this.orders.forEach(o => {
hash[o.supplier_name] = hash[o.supplier_name] + 1 || 1;
})
const suppliers = Object.keys(hash).map(name => ({ name: name, num: hash[name] }))
console.log(suppliers);
}
This uses an object hash (dictionary) without lodash to store the supplier / count key-value pair, and removes the excess finds / program logic / lodash.
来源:https://stackoverflow.com/questions/65708924/how-to-change-a-property-of-an-object-in-vue