好的,我一直试图创建正确的算法来解决这个问题一周,我似乎没有采用正确的方法。 我有一个对象数组,我需要通过多个属性进行分组,但也有能力在x prop处打破。例如:
var arr = [
{car: 'ford', model: 'mustang', color: 'black', price: 400},
{car: 'ford', model: 'focus', color: 'yellow', price: 300},
{car: 'toyota', model: 'corolla', color: 'blue', price: 100},
{car: 'toyota', model: 'camry', color: 'green', price: 200},
{car: 'toyota', model: 'camry', color: 'black', price: 250},
{car: 'toyota', model: 'camry', color: 'black', price: 350},
]
然后groupBy(arr, ['car', 'model', 'color'], {break: 'model'})
这会打印类似
的内容[
{
"ford - mustang": [
"black": [
{car: 'ford', model: 'mustang', color: 'black', price: 400}
]
]
},
{
"ford - focus": [
"yellow": [
{car: 'ford', model: 'focus', color: 'yellow', price: 300}
]
]
},
{
"toyota - corolla": [
"blue": [
{car: 'toyota', model: 'corolla', color: 'blue', price: 100},
]
]
},
{
"toyota - camry": [
"green": [
{car: 'toyota', model: 'camry', color: 'green', price: 200}
],
"black": [
{car: 'toyota', model: 'camry', color: 'black', price: 250},
{car: 'toyota', model: 'camry', color: 'black', price: 350}
]
]
}
]
编辑1:这是我创建的分组功能。这个功能考虑了三个道具"标准1,标准2和标准3",这个功能完成了分组工作但是我还没有弄清楚如何做破坏部分
const criteriaMapping = {
Lenders: "lenderStr",
Branches: "branchStr",
Officers: "officerStr",
Programs: "programStr",
Stages: "stageStr"
}
private createNewArray(data){
let keys1 = []
let keys2 = []
let keys3 = []
let result = []
let orderBy = 'reservationNo'
let orderByDirection1 = ''
let orderByDirection2 = ''
let orderByDirection3 = ''
if(this.query.criteria1.description){
keys1 = Object.keys(_.groupBy(data, criteriaMapping[this.query.criteria1.description]))
orderByDirection1 = this.query.criteria1.desc ? 'desc' : 'asc'
}
if(this.query.criteria1.description && this.query.criteria2.description){
keys2 = Object.keys(_.groupBy(data, criteriaMapping[this.query.criteria2.description]))
orderByDirection2 = this.query.criteria2.desc ? 'desc' : 'asc'
}
if(this.query.criteria2.description && this.query.criteria3.description){
keys3 = Object.keys(_.groupBy(data, criteriaMapping[this.query.criteria3.description]))
orderByDirection3 = this.query.criteria3.desc ? 'desc' : 'asc'
}
let i = 0
do{
let j = 0
do{
let k = 0
do{
let orderProp = criteriaMapping[this.query.criteria1.description]
let order = 'asc'
if(keys3[k])
order = orderByDirection3
else if(keys2[j])
order = orderByDirection2
else if(keys1[i])
order = orderByDirection1
let concat = _.orderBy(data.filter(x => {
return (keys1[i] ? x[criteriaMapping[this.query.criteria1.description]] === keys1[i] : true)
&& (keys2[j] ? x[criteriaMapping[this.query.criteria2.description]] === keys2[j] : true)
&& (keys3[k] ? x[criteriaMapping[this.query.criteria3.description]] === keys3[k] : true)
}), ['reservationNo'], [order])
if(concat && concat.length){
if(keys1[i]) result.push({"header": true, 0: keys1[i], 1: keys2[j], 2: keys3[k]})
result = result.concat(concat)
}
k++
}while(keys3.length > k)
j++
}while (keys2.length > j)
i++
}while (keys1.length > i)
return result
}
所以我不认为我让自己清楚了(我的错)。休息部分很难解释我会尝试更好地解释它。所以如果我要打电话,我先前写过的数组
groupBy(arr, ['car', 'model', 'color'], {break: 'model'})
它会打印
{
"ford - mustang": {
"black": Array(1)
},
"ford - focus": {
"yellow": Array(1)
},
"toyota - corolla": {
"blue": Array(1)
},
"toyota - camry": {
"green": Array(1),
"black": Array(2)
}
}
现在,如果我打电话
groupBy(arr, ['car', 'model', 'color'], {break: 'car'})
它会打印
{
"ford": {
"mustang - black": Array(1),
"focus - yellow": Array(1)
},
"toyota": {
"corolla - blue": Array(1),
"camry - green": Array(1),
"camry - black": Array(2)
}
}
答案 0 :(得分:2)
您可以使用reduce()
方法。
var arr = [
{car: 'ford', model: 'mustang', color: 'black', price: 400},
{car: 'ford', model: 'focus', color: 'yellow', price: 300},
{car: 'toyota', model: 'corolla', color: 'blue', price: 100},
{car: 'toyota', model: 'camry', color: 'green', price: 200},
{car: 'toyota', model: 'camry', color: 'black', price: 250},
{car: 'toyota', model: 'camry', color: 'black', price: 350},
]
var result = arr.reduce(function(r, e) {
let cm = `${e.car} - ${e.model}`;
if (!r[cm]) r[cm] = {}
if (!r[cm][e.color]) r[cm][e.color] = [];
r[cm][e.color].push(e);
return r;
}, {})
console.log(result)
您还可以使用reduce()
创建自定义功能以获得更加动态的解决方案。
var arr = [
{car: 'ford', model: 'mustang', color: 'black', price: 400},
{car: 'ford', model: 'focus', color: 'yellow', price: 300},
{car: 'toyota', model: 'corolla', color: 'blue', price: 100},
{car: 'toyota', model: 'camry', color: 'green', price: 200},
{car: 'toyota', model: 'camry', color: 'black', price: 250},
{car: 'toyota', model: 'camry', color: 'black', price: 350},
]
function groupBy(data, group, {divide} = {}) {
return arr.reduce(function(r, e) {
let d = e[divide], cm = group
.filter(a => a != divide)
.map(a => e[a]).join(' - ')
if(!r[cm]) r[cm] = divide ? {} : []
if(!r[cm][d] && divide) r[cm][d] = [];
divide ? r[cm][d].push(e) : r[cm].push(e)
return r;
}, {})
}
let result = groupBy(arr, ['car', 'model', 'color'], {divide: 'model'})
let result2 = groupBy(arr, ['car', 'model', 'color'], {divide: 'car'})
let result3 = groupBy(arr, ['car', 'color'])
console.log(result)
console.log(result2)
console.log(result3)
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:1)
这是你在找什么?
function groupBy(arr, keys, breakVal){
return arr.reduce( (grouped, next) => {
var idx = keys.reduce( (idx, nextkey) => {
idx.push(next[nextkey])
return idx;
}, [] ).join(' - ')
if(breakVal){
if(!grouped[idx]) {
grouped[idx] = {}
}
if(!grouped[idx][next[breakVal]]) {
grouped[idx][next[breakVal]] = [];
}
grouped[idx][next[breakVal]].push(next);
}else{
if(!grouped[idx]) {
grouped[idx] = [];
}
grouped[idx].push(next);
}
return grouped;
}, {})
}
console.log(groupBy(arr, ['car', 'color'], 'model'))
答案 2 :(得分:0)
感谢@Nenad和@asosnovsky,我能够提出一个满足我需求的功能
function groupBy(arr, props, dividers){
return arr.reduce((r, e) => {
var prop = []
var divide = []
for(var i = 0; i < props.length; i++){
prop.push(e[props[i]])
}
for(var i = 0; i < dividers.length; i++){
divide.push(e[dividers[i]])
}
prop = prop.join(' - ')
divide = divide.join(' - ')
if(!r[prop]) r[prop] = divide ? {} : []
if(divide){
if(!r[prop][divide]) r[prop][divide] = []
r[prop][divide].push(e)
}else
r[prop].push(e)
return r
}, {})
}
非常感谢你。