Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 数组按属性分组到数组数组中_Javascript_Arrays_Group By - Fatal编程技术网

Javascript 数组按属性分组到数组数组中

Javascript 数组按属性分组到数组数组中,javascript,arrays,group-by,Javascript,Arrays,Group By,好的,我已经尝试创建正确的算法来解决这个问题一周了,我似乎没有找到正确的方法。 我有一个数组的对象,我需要分组多个属性,但也有能力打破在x道具。例如: var arr = [ {car: 'ford', model: 'mustang', color: 'black', price: 400}, {car: 'ford', model: 'focus', color: 'yellow', price: 300}, {car: 'toyota', model: 'corolla', colo

好的,我已经尝试创建正确的算法来解决这个问题一周了,我似乎没有找到正确的方法。 我有一个数组的对象,我需要分组多个属性,但也有能力打破在x道具。例如:

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:这是我创建的分组依据函数。这个函数考虑了三个支柱“criteria1、criteria2和criteria3”,这个函数完成分组工作,但是我还没有弄清楚如何完成分解部分

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)
 }
}
{
 "ford": {
  "mustang - black": Array(1),
  "focus - yellow": Array(1)
 },
 "toyota": {
  "corolla - blue": Array(1),
  "camry - green": Array(1),
  "camry - black": Array(2)
 }
}
现在如果我打电话

groupBy(arr,['car','model','color',{break:'car'})

它会打印出来

{
 "ford - mustang": {
  "black": Array(1)
 },
 "ford - focus": {
   "yellow": Array(1)
 },
 "toyota - corolla": {
  "blue": Array(1)
 },
 "toyota - camry": {
  "green": Array(1),
  "black": Array(2)
 }
}
{
 "ford": {
  "mustang - black": Array(1),
  "focus - yellow": Array(1)
 },
 "toyota": {
  "corolla - blue": Array(1),
  "camry - green": Array(1),
  "camry - black": Array(2)
 }
}
您可以为此使用
reduce()
方法

var-arr=[
{汽车:“福特”,车型:“野马”,颜色:“黑色”,价格:400},
{汽车:'ford',车型:'focus',颜色:'yellow',价格:300},
{汽车:'toyota',车型:'corolla',颜色:'blue',价格:100},
{汽车:“丰田”,车型:“凯美瑞”,颜色:“绿色”,价格:200},
{汽车:“丰田”,车型:“凯美瑞”,颜色:“黑色”,价格:250},
{汽车:“丰田”,车型:“凯美瑞”,颜色:“黑色”,价格:350},
]
var结果=arr.REDUCT(函数(r,e){
设cm=`${e.car}-${e.model}`;
如果(!r[cm])r[cm]={}
如果(!r[cm][e.color])r[cm][e.color]=[];
r[cm][e.color].push(e);
返回r;
}, {})

console.log(result)
这就是您要找的吗

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'))

多亏了@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
}, {})
功能分组依据(arr、道具、分割器){
返回arr.reduce((r,e)=>{
var prop=[]
var divide=[]
对于(变量i=0;i
}


非常感谢。

您能告诉我们您的尝试,以便我们帮助您找到一个有效的解决方案吗?为什么要用这种方式格式化数据(使用单个键的对象数组)而不是使用多个键的单个对象?@AndrewLohr刚刚更新了我的question@Damon奇怪的是,这不是OP描述的输出(要求使用一个单键的对象数组)
[result]
,已修复。@NenadVracar这太棒了,非常接近我想要的内容。我不认为使用reduce()可以实现这一点,但是断点可以是动态的。例如groupBy(arr,['car','model','color',{break:'car})这是接近我需要的,我只是更新我的问题,请看我的编辑,我试图更好地解释自己。谢谢