programing

속성에 따라 개체 배열을 별도의 배열로 분할

muds 2023. 10. 8. 10:26
반응형

속성에 따라 개체 배열을 별도의 배열로 분할

내게 이런 배열이 있다고 치자.

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");

@denolssonTypeScript 구현 기능 개선:

/**
 * 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

반응형