속성에 따라 개체 배열을 별도의 배열로 분할
내게 이런 배열이 있다고 치자.
var arr = [
{type:"orange", title:"First"},
{type:"orange", title:"Second"},
{type:"banana", title:"Third"},
{type:"banana", title:"Fourth"}
];
그리고 나는 이것을 같은 종류의 객체를 가진 배열로 나누었으면 합니다.
[{type:"orange", title:"First"},
{type:"orange", title:"Second"}]
[{type:"banana", title:"Third"},
{type:"banana", title:"Fourth"}]
하지만 오렌지나 바나나를 명시한 if문이 없기 때문에 이것을 일반적으로 하고 싶습니다.
// not like this
for (prop in arr){
if (arr[prop] === "banana"){
//add to new array
}
}
생각은?JQuery와 언더스코어 모두 사용할 수 있는 옵션입니다.
이 작업은 다음과 같은 경우에 쉬운 작업입니다.
function groupBy(arr, property) {
return arr.reduce(function(memo, x) {
if (!memo[x[property]]) { memo[x[property]] = []; }
memo[x[property]].push(x);
return memo;
}, {});
}
var o = groupBy(arr, 'type'); // => {orange:[...], banana:[...]}
o.orange; // => [{"type":"orange","title":"First"},{"type":"orange","title":"Second"}]
o.banana; // => [{"type":"banana","title":"Third"},{"type":"banana","title":"Fourth"}]
물론 대상 브라우저가 ECMAscript 262 5판을 지원하지 않는 경우 직접 "축소"를 구현하거나, 폴리필 라이브러리를 사용하거나, 다른 답변을 선택해야 합니다.
[업데이트] 자바스크립트의 모든 버전에서 작동하는 솔루션은 다음과 같습니다.
function groupBy2(xs, prop) {
var grouped = {};
for (var i=0; i<xs.length; i++) {
var p = xs[i][prop];
if (!grouped[p]) { grouped[p] = []; }
grouped[p].push(xs[i]);
}
return grouped;
}
JQuery와 언더스코어 모두 사용할 수 있는 옵션입니다.
언더스코어는 당신이 필요로 하는 것을 정확하게 해줍니다.
_.groupBy(arr, "type")
ES6 솔루션:
function groupBy(arr, property) {
return arr.reduce((acc, cur) => {
acc[cur[property]] = [...acc[cur[property]] || [], cur];
return acc;
}, {});
}
또는 완전히 ES6fy:
const groupBy = (arr, property) => {
return arr.reduce((acc, cur) => {
acc[cur[property]] = [...acc[cur[property]] || [], cur];
return acc;
}, {});
}
도움이 됐으면 좋겠네요!
여기서는 개체 배열을 가정합니다.
function groupBy(array, property) {
var hash = {};
for (var i = 0; i < array.length; i++) {
if (!hash[array[i][property]]) hash[array[i][property]] = [];
hash[array[i][property]].push(array[i]);
}
return hash;
}
groupBy(arr,'type') // Object {orange: Array[2], banana: Array[2]}
groupBy(arr,'title') // Object {First: Array[1], Second: Array[1], Third: Array[1], Fourth: Array[1]}
제목에 따라 개체를 저장하는 사전을 작성하면 됩니다.이렇게 할 수 있습니다.
js
var arr = [
{type:"orange", title:"First"},
{type:"orange", title:"Second"},
{type:"banana", title:"Third"},
{type:"banana", title:"Fourth"}
];
var sorted = {};
for( var i = 0, max = arr.length; i < max ; i++ ){
if( sorted[arr[i].type] == undefined ){
sorted[arr[i].type] = [];
}
sorted[arr[i].type].push(arr[i]);
}
console.log(sorted["orange"]);
console.log(sorted["banana"]);
jsfiddle 데모: http://jsfiddle.net/YJnM6/
스크립트 버전을 입력합니다.
/**
* Group object array by property
* Example, groupBy(array, ( x: Props ) => x.id );
* @param array
* @param property
*/
export const groupBy = <T>(array: Array<T>, property: (x: T) => string): { [key: string]: Array<T> } =>
array.reduce((memo: { [key: string]: Array<T> }, x: T) => {
if (!memo[property(x)]) {
memo[property(x)] = [];
}
memo[property(x)].push(x);
return memo;
}, {});
export default groupBy;
예를 들어, 우리가 타입을 언급하고 싶지 않다면 우리는 이와 같이 달성할 수 있습니다.
var arr = [
{type:"orange", title:"First"},
{type:"orange", title:"Second"},
{type:"banana", title:"Third"},
{type:"banana", title:"Fourth"}
];
const fun = (ar)=>{
let temp ={}
for(e of ar){
!temp[e.type] ? temp[e.type]=[e] : temp[e.type].push(e)
}
return temp
}
console.log(fun(arr))
https://lodash.com/docs/4.17.15#groupBy 을 이용할 수도 있습니다.
그것은 당신의 목적에 도움이 될 것입니다.
개체 대신 배열을 반환하라는 @Watchmaker의 답변을 약간 수정합니다.
function groupBy(arr, key) {
return arr.reduce((acc, cur) => {
acc[cur[key]] = [...acc[cur[key]] || [], cur];
return acc;
}, []).filter(Boolean);
}
다른 활자 스크립트 버전
원래 @denolsson의 답변에서 영감을 받았지만 현재 내부 배열에서 중복되어 키로 사용되는 속성을 제거합니다.
가독성을 높이고 린터를 행복하게 하기 위해 일부 다른 것들도 변경 및 이름 변경)
/**
* Inspired by https://stackoverflow.com/a/53632546/7869582
*/
private groupBy<T>(array: Array<T>, property: keyof T): { [key: string]: Array<T> } {
return array.reduce(
(objectToBeBuilt: { [key: string]: Array<T> }, arrayElem: T) => {
const newOuterIdx = arrayElem[property] as unknown as string;
if (!objectToBeBuilt[newOuterIdx]) {
objectToBeBuilt[newOuterIdx] = [];
}
if (arrayElem[property]) {
delete arrayElem[property];
}
objectToBeBuilt[newOuterIdx]?.push(arrayElem);
return objectToBeBuilt;
},
{} // initial value of objectToBeBuild
);
}
사용 예시:
const resultGroupedByCustomer = this.groupBy(result.rows, "customer_id");
@denolsson의 TypeScript 구현 기능 개선:
/**
* Group an array of objects by a specified property.
* @param {Array<T>} array - The array of objects to group.
* @param {string} property - The property to group the objects by.
* @returns {Object} An object where the keys are the unique values of the specified property and the values are arrays of objects with that property value.
* @template T
*
* @example
* const arr = [{type:"A"}, {type:"A"}, {type:"B"}];
* const result = groupBy(arr, "type");
* console.log(result); // Output: { A: [{type: "A"}, {type: "A"}], B: [{type: "B"}] }
*/
export function groupBy<T>(array: Array<T>, property: string): { [key: string]: Array<T> } {
return array.reduce((memo: { [key: string]: Array<T> }, x: T) => {
memo[x[property]] ||= [];
memo[x[property]].push(x);
return memo;
}, {});
}
그리고 자바스크립트 버전:
export function groupBy(array, property) {
return array.reduce((memo, x) => {
memo[x[property]] ||= [];
memo[x[property]].push(x);
return memo;
}, {});
}
언급URL : https://stackoverflow.com/questions/14696326/break-array-of-objects-into-separate-arrays-based-on-a-property
'programing' 카테고리의 다른 글
fstream의 peek에 해당하는 C (0) | 2023.10.08 |
---|---|
jQuery에서 사용하는 방법 :not and hasClass()에서 클래스 없이 특정 요소를 가져오는 방법 (0) | 2023.10.08 |
HTMLHTML파일 선택 이벤트파일 선택 이벤트 (0) | 2023.10.08 |
mysql 대신 Xampp가 MariaDB에 연결됨(KNP/SymfonyCasts 튜토리얼 "데이터베이스 말하는 법") (0) | 2023.10.08 |
xpath를 사용하여 노드의 N번째 자식 가져오기 (0) | 2023.10.08 |