按嵌套键分组数组

时间:2017-12-10 02:14:00

标签: javascript arrays ecmascript-6 ramda.js

有没有人知道ES6或Ramda通过对象键对对象数组进行分组的方法,然后根据分组创建一个新的对象数组?例如,我有一个对象数组如下:

[
  {
    "name": "ABCD123",
    "code": "GFDGF",
    "ptj": {
      "code": "123",
      "desc": "ABCD 123"
    }
  },
  {
    "name": "ANGGUN",
    "code": "DSFD54",
    "ptj": {
      "code": "111",
      "desc": "111 123"
    }
  },
  {
    "name": "GDFDGG",
    "code": "HJ2",
    "ptj": {
      "code": "111",
      "desc": "111 123"
    }
  },
  {
    "name": "POT",
    "code": "POT89",
    "ptj": {
      "code": "222",
      "desc": "222 123"
    }
  },
  {
    "name": "POTER UTAMA",
    "code": "POTER345",
    "ptj": {
      "code": "123",
      "desc": "ABCD 123"
    }
  },
  {
    "name": "ABCD123ABCD",
    "code": "LOLL23",
    "ptj": {
      "code": "123",
      "desc": "ABCD 123"
    }
  },
  {
    "name": "ANGGUN 2",
    "code": "DSFD54",
    "ptj": {
      "code": "111",
      "desc": "111 123"
    }
  },
  {
    "name": "GDFDGG",
    "code": "HJ2",
    "ptj": {
      "code": "111",
      "desc": "111 123"
    }
  },
  {
    "name": "POT",
    "code": "POT89",
    "ptj": {
      "code": "222",
      "desc": "222 123"
    }
  },
  {
    "name": "POTER UTAMA",
    "code": "POTER345",
    "ptj": {
      "code": "123",
      "desc": "ABCD 123"
    }
  }
]

我希望有一个按ptj.descptj.code分组的新数组:

[
  {
    "PTJ": "ABCD 123",
    "data": [
      {
        "name": "ABCD123",
        "code": "GFDGF",
        "ptj": {
          "code": "123",
          "desc": "ABCD 123"
        }
      },
      {
        "name": "POTER UTAMA",
        "code": "POTER345",
        "ptj": {
          "code": "123",
          "desc": "ABCD 123"
        }
      },
      {
        "name": "ABCD123ABCD",
        "code": "LOLL23",
        "ptj": {
          "code": "123",
          "desc": "ABCD 123"
        }
      },
      {
        "name": "POTER UTAMA",
        "code": "POTER345",
        "ptj": {
          "code": "123",
          "desc": "ABCD 123"
        }
      }
    ]
  },
  {
    "PTJ": "111 123",
    "data": [
      {
        "name": "ANGGUN",
        "code": "DSFD54",
        "ptj": {
          "code": "111",
          "desc": "111 123"
        }
      },
      {
        "name": "GDFDGG",
        "code": "HJ2",
        "ptj": {
          "code": "111",
          "desc": "111 123"
        }
      },
      {
        "name": "ANGGUN 2",
        "code": "DSFD54",
        "ptj": {
          "code": "111",
          "desc": "111 123"
        }
      },
    ]
  },
  {
    "PTJ": "222 123",
    "data": [
      {
        "name": "POT",
        "code": "POT89",
        "ptj": {
          "code": "222",
          "desc": "222 123"
        }
      },
      {
        "name": "POT",
        "code": "POT89",
        "ptj": {
          "code": "222",
          "desc": "222 123"
        }
      },
    ]
  }
]

到目前为止我所拥有的是

const stores = myArray.reduce((r, a) => {
    r[a.ptj.desc] = r[a.ptj.desc] || [];
    r[a.ptj.desc].push(a);
    return r;
}, {});

不幸的是它转换为对象而我无法使用array.map。我做错了什么?我欢迎使用ES6或ramda进行纠正和改进。提前致谢

4 个答案:

答案 0 :(得分:1)

如果您只想对具有相同ptj.desc值的对象进行分组,并且不介意结果值是具有键索引的对象,那么您可以使用R.groupBy之类的这样:



const data = [
  {
    "name": "ABCD123",
    "code": "GFDGF",
    "ptj": {
      "code": "123",
      "desc": "ABCD 123"
    }
  },
  {
    "name": "ANGGUN",
    "code": "DSFD54",
    "ptj": {
      "code": "111",
      "desc": "111 123"
    }
  },
  {
    "name": "GDFDGG",
    "code": "HJ2",
    "ptj": {
      "code": "111",
      "desc": "111 123"
    }
  },
  {
    "name": "POT",
    "code": "POT89",
    "ptj": {
      "code": "222",
      "desc": "222 123"
    }
  },
  {
    "name": "POTER UTAMA",
    "code": "POTER345",
    "ptj": {
      "code": "123",
      "desc": "ABCD 123"
    }
  },
  {
    "name": "ABCD123ABCD",
    "code": "LOLL23",
    "ptj": {
      "code": "123",
      "desc": "ABCD 123"
    }
  },
  {
    "name": "ANGGUN 2",
    "code": "DSFD54",
    "ptj": {
      "code": "111",
      "desc": "111 123"
    }
  },
  {
    "name": "GDFDGG",
    "code": "HJ2",
    "ptj": {
      "code": "111",
      "desc": "111 123"
    }
  },
  {
    "name": "POT",
    "code": "POT89",
    "ptj": {
      "code": "222",
      "desc": "222 123"
    }
  },
  {
    "name": "POTER UTAMA",
    "code": "POTER345",
    "ptj": {
      "code": "123",
      "desc": "ABCD 123"
    }
  }
]

const fn = R.groupBy(R.path(['ptj','desc']))

console.log(fn(data))

<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
&#13;
&#13;
&#13;

如果您确实想要与问题中的示例结构相同,那么您可以使用R.mapR.zipObjR.toPairs来构建上述内容,如下所示:

&#13;
&#13;
const data = [
  {
    "name": "ABCD123",
    "code": "GFDGF",
    "ptj": {
      "code": "123",
      "desc": "ABCD 123"
    }
  },
  {
    "name": "ANGGUN",
    "code": "DSFD54",
    "ptj": {
      "code": "111",
      "desc": "111 123"
    }
  },
  {
    "name": "GDFDGG",
    "code": "HJ2",
    "ptj": {
      "code": "111",
      "desc": "111 123"
    }
  },
  {
    "name": "POT",
    "code": "POT89",
    "ptj": {
      "code": "222",
      "desc": "222 123"
    }
  },
  {
    "name": "POTER UTAMA",
    "code": "POTER345",
    "ptj": {
      "code": "123",
      "desc": "ABCD 123"
    }
  },
  {
    "name": "ABCD123ABCD",
    "code": "LOLL23",
    "ptj": {
      "code": "123",
      "desc": "ABCD 123"
    }
  },
  {
    "name": "ANGGUN 2",
    "code": "DSFD54",
    "ptj": {
      "code": "111",
      "desc": "111 123"
    }
  },
  {
    "name": "GDFDGG",
    "code": "HJ2",
    "ptj": {
      "code": "111",
      "desc": "111 123"
    }
  },
  {
    "name": "POT",
    "code": "POT89",
    "ptj": {
      "code": "222",
      "desc": "222 123"
    }
  },
  {
    "name": "POTER UTAMA",
    "code": "POTER345",
    "ptj": {
      "code": "123",
      "desc": "ABCD 123"
    }
  }
]

const fn = R.groupBy(R.path(['ptj','desc']))

const fn2 = R.compose(R.map(R.zipObj(['PTJ', 'data'])), R.toPairs, fn)

console.log(fn2(data))
&#13;
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

还有其他方法可以做到这一点,但你在这里描述的内容符合id =&gt; val查找。

首先创建一个包含所有键的数组(所以{}.ptj.desc),然后将所有对象映射到一个新对象(map),其键与上面的数组匹配,然后是...... profit。

见下面的例子。希望这是你正在寻找的。

&#13;
&#13;
var mainStore = [
  {
    "name": "ABCD123",
    "code": "GFDGF",
    "ptj": {
      "code": "123",
      "desc": "ABCD 123"
    }
  },
  {
    "name": "ANGGUN",
    "code": "DSFD54",
    "ptj": {
      "code": "111",
      "desc": "111 123"
    }
  },
  {
    "name": "GDFDGG",
    "code": "HJ2",
    "ptj": {
      "code": "111",
      "desc": "111 123"
    }
  },
  {
    "name": "POT",
    "code": "POT89",
    "ptj": {
      "code": "222",
      "desc": "222 123"
    }
  },
  {
    "name": "POTER UTAMA",
    "code": "POTER345",
    "ptj": {
      "code": "123",
      "desc": "ABCD 123"
    }
  },
  {
    "name": "ABCD123ABCD",
    "code": "LOLL23",
    "ptj": {
      "code": "123",
      "desc": "ABCD 123"
    }
  },
  {
    "name": "ANGGUN 2",
    "code": "DSFD54",
    "ptj": {
      "code": "111",
      "desc": "111 123"
    }
  },
  {
    "name": "GDFDGG",
    "code": "HJ2",
    "ptj": {
      "code": "111",
      "desc": "111 123"
    }
  },
  {
    "name": "POT",
    "code": "POT89",
    "ptj": {
      "code": "222",
      "desc": "222 123"
    }
  },
  {
    "name": "POTER UTAMA",
    "code": "POTER345",
    "ptj": {
      "code": "123",
      "desc": "ABCD 123"
    }
  }
];

var idList = mainStore.map(item => item.ptj.desc);

var dataMap = mainStore.reduce(( dataMap, item ) => {
  dataMap[ item.ptj.desc ] = item;
  return dataMap;
}, {});

// Then do everything based on idList 

var onlyCodes = idList.map(id => dataMap[ id ].ptj.code);
var onlyNames = idList.map(id => dataMap[ id ].name);

console.log(onlyCodes);
console.log(onlyNames);
&#13;
&#13;
&#13;

答案 2 :(得分:0)

您可以使用reduce()ptj.descptj.code进行分组。以下示例使用ptj.desc

let proj = [{"name":"ABCD123","code":"GFDGF","ptj":{"code":"123","desc":"ABCD 123"}},{"name":"ANGGUN","code":"DSFD54","ptj":{"code":"111","desc":"111 123"}},{"name":"GDFDGG","code":"HJ2","ptj":{"code":"111","desc":"111 123"}},{"name":"POT","code":"POT89","ptj":{"code":"222","desc":"222 123"}},{"name":"POTER UTAMA","code":"POTER345","ptj":{"code":"123","desc":"ABCD 123"}},{"name":"ABCD123ABCD","code":"LOLL23","ptj":{"code":"123","desc":"ABCD 123"}},{"name":"ANGGUN 2","code":"DSFD54","ptj":{"code":"111","desc":"111 123"}},{"name":"GDFDGG","code":"HJ2","ptj":{"code":"111","desc":"111 123"}},{"name":"POT","code":"POT89","ptj":{"code":"222","desc":"222 123"}},{"name":"POTER UTAMA","code":"POTER345","ptj":{"code":"123","desc":"ABCD 123"}}]

result = proj.reduce(function (a, c) {
  a[c.ptj.desc] = a[c.ptj.desc] || [];
  a[c.ptj.desc].push(c)
  return a;
}, Object.create(null));
console.log(result);

答案 3 :(得分:-1)

如果你想使用地图,你可以尝试这样的事情:

let yourArray = Object.keys(stores).map(key => stores[key])