있지만 LINQ의 대답이 재미있다, 그것은 또한 아주 무거운 무게입니다. 내 접근 방식은 다소 다릅니다.
var DataGrouper = (function() {
var has = function(obj, target) {
return _.any(obj, function(value) {
return _.isEqual(value, target);
});
};
var keys = function(data, names) {
return _.reduce(data, function(memo, item) {
var key = _.pick(item, names);
if (!has(memo, key)) {
memo.push(key);
}
return memo;
}, []);
};
var group = function(data, names) {
var stems = keys(data, names);
return _.map(stems, function(stem) {
return {
key: stem,
vals:_.map(_.where(data, stem), function(item) {
return _.omit(item, names);
})
};
});
};
group.register = function(name, converter) {
return group[name] = function(data, names) {
return _.map(group(data, names), converter);
};
};
return group;
}());
DataGrouper.register("sum", function(item) {
return _.extend({}, item.key, {Value: _.reduce(item.vals, function(memo, node) {
return memo + Number(node.Value);
}, 0)});
});
JSBin에서 실제로 볼 수 있습니다 .
Underscore에서 has
누락 된 내용 이 있지만 그 기능을 수행하는 것을 보지 못했습니다 . 와 거의 동일 _.contains
하지만 비교 _.isEqual
보다는 사용합니다 ===
. 그 외에는 일반적인 시도가 있지만 나머지는 문제에 따라 다릅니다.
이제 DataGrouper.sum(data, ["Phase"])
반환
[
{Phase: "Phase 1", Value: 50},
{Phase: "Phase 2", Value: 130}
]
그리고 DataGrouper.sum(data, ["Phase", "Step"])
반환
[
{Phase: "Phase 1", Step: "Step 1", Value: 15},
{Phase: "Phase 1", Step: "Step 2", Value: 35},
{Phase: "Phase 2", Step: "Step 1", Value: 55},
{Phase: "Phase 2", Step: "Step 2", Value: 75}
]
그러나 sum
여기서는 하나의 잠재적 기능 일뿐입니다. 원하는대로 다른 사람을 등록 할 수 있습니다.
DataGrouper.register("max", function(item) {
return _.extend({}, item.key, {Max: _.reduce(item.vals, function(memo, node) {
return Math.max(memo, Number(node.Value));
}, Number.NEGATIVE_INFINITY)});
});
이제 DataGrouper.max(data, ["Phase", "Step"])
돌아올 것이다
[
{Phase: "Phase 1", Step: "Step 1", Max: 10},
{Phase: "Phase 1", Step: "Step 2", Max: 20},
{Phase: "Phase 2", Step: "Step 1", Max: 30},
{Phase: "Phase 2", Step: "Step 2", Max: 40}
]
또는 이것을 등록한 경우 :
DataGrouper.register("tasks", function(item) {
return _.extend({}, item.key, {Tasks: _.map(item.vals, function(item) {
return item.Task + " (" + item.Value + ")";
}).join(", ")});
});
전화 DataGrouper.tasks(data, ["Phase", "Step"])
하면 당신을 얻을 것이다
[
{Phase: "Phase 1", Step: "Step 1", Tasks: "Task 1 (5), Task 2 (10)"},
{Phase: "Phase 1", Step: "Step 2", Tasks: "Task 1 (15), Task 2 (20)"},
{Phase: "Phase 2", Step: "Step 1", Tasks: "Task 1 (25), Task 2 (30)"},
{Phase: "Phase 2", Step: "Step 2", Tasks: "Task 1 (35), Task 2 (40)"}
]
DataGrouper
그 자체가 함수입니다. 데이터와 그룹화하려는 속성 목록으로 호출 할 수 있습니다. 요소가 두 개의 속성을 가진 객체 인 배열을 반환합니다. key
그룹화 된 속성의 모음이고 vals
키에없는 나머지 속성을 포함하는 객체의 배열입니다. 예를 들어 다음 DataGrouper(data, ["Phase", "Step"])
을 산출합니다.
[
{
"key": {Phase: "Phase 1", Step: "Step 1"},
"vals": [
{Task: "Task 1", Value: "5"},
{Task: "Task 2", Value: "10"}
]
},
{
"key": {Phase: "Phase 1", Step: "Step 2"},
"vals": [
{Task: "Task 1", Value: "15"},
{Task: "Task 2", Value: "20"}
]
},
{
"key": {Phase: "Phase 2", Step: "Step 1"},
"vals": [
{Task: "Task 1", Value: "25"},
{Task: "Task 2", Value: "30"}
]
},
{
"key": {Phase: "Phase 2", Step: "Step 2"},
"vals": [
{Task: "Task 1", Value: "35"},
{Task: "Task 2", Value: "40"}
]
}
]
DataGrouper.register
함수를 허용하고 그룹화 할 초기 데이터 및 특성을 승인하는 새 함수를 작성합니다. 이 새로운 함수는 위와 같이 출력 형식을 가져 와서 각각에 대해 함수를 실행하여 새로운 배열을 반환합니다. 생성 된 함수는 DataGrouper
제공 한 이름 에 따라 속성으로 저장되며 로컬 참조를 원할 경우 반환됩니다.
글쎄요, 그것은 많은 설명입니다. 코드는 매우 간단합니다.