2017-12-02 8 views
0

私はちょうどロダッシュについて学び始め、それを自分のコードに組み込もうとしました。あなたが見ることができるように私は従業員の下の各要素の重みを追加しています。問題は私が抱えていることです。最終的なデータの配列に3番目の要素「性別」をどうやって取得するかわかりません。私はこのReduce array of objects on key and sum value into arrayを使って私のlodashコードを作りました。私の出力をどのように取得しようとしているかについては、以下を参照してください。ここでオブジェクトの配列のlodashの合計

var userAns = [{ 
 
    id: 1, 
 
    text: "answer1", 
 
    employee: [{ 
 
     name: "John", 
 
     weight: 3, 
 
     gender: "male" 
 
     }, 
 
     { 
 
     name: "Sally", 
 
     weight: 4, 
 
     gender: "female" 
 
     } 
 
    ] 
 
    }, 
 
    { 
 
    id: 2, 
 
    text: "answer2", 
 
    employee: [{ 
 
     name: "John", 
 
     weight: 6, 
 
     gender: "male" 
 
     }, 
 
     { 
 
     name: "Sally", 
 
     weight: 3, 
 
     gender: "female" 
 
     } 
 
    ] 
 
    } 
 
]; 
 

 
var scores = []; 
 
for (var i = 0; i < userAns.length; i++) { 
 
    for (var j = 0; j < userAns[i].employee.length; j++) { 
 
    scores.push(userAns[i].employee[j]); 
 
    } 
 
} 
 

 
var result = _(scores) 
 
    .map('name') 
 
    .uniq() 
 
    .map(function(key) { 
 

 
    return { 
 
     name: key, 
 
     score: _(scores).filter({ 
 
     name: key 
 
     }).sumBy('weight') 
 
    }; 
 
    }) 
 
    .value(); 
 

 
console.log(result);
<script src="https://cdn.jsdelivr.net/lodash/4.14.1/lodash.min.js"></script>

どのキー私は私の配列

[ 
 
    { 
 
    "name": "John", 
 
    "score": 9, 
 
    "gender": "male" 
 
    }, 
 
    { 
 
    "name": "Sally", 
 
    "score": 7, 
 
    "gender":"female" 
 
    } 
 
]

答えて

1

を使用して出力を得る:

あなたは_.flatMap()_.groupBy()_.map()_.mergeWith()を組み合わせて使用​​することができます。

var userAns = [{"id":1,"text":"answer1","employee":[{"name":"John","weight":3,"gender":"male"},{"name":"Sally","weight":4,"gender":"female"}]},{"id":2,"text":"answer2","employee":[{"name":"John","weight":6,"gender":"male"},{"name":"Sally","weight":3,"gender":"female"}]}]; 
 

 
var result = _(userAns) 
 
    .flatMap('employee') // create an array of all emplyoees 
 
    .groupBy('name') // create groups of employees with the same name 
 
    .map(function(g) { 
 
    // merge each group to a single object, and combine weight values 
 
    return _.mergeWith.apply(_, [{}].concat(g, function(obj, src, key) { 
 
     return key === 'weight' ? (obj || 0) + src : undefined; 
 
    })); 
 
    }) 
 
    .value(); 
 
    
 
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
配列の配列を取得し、 Array#concatspreadingにより平坦化する

使用Array#map:ES6を使用

ReduceMapへの配列は、その後、Map#valuesイテレータを広げることにより、配列に戻って変換する:あなたはマイナーな変更をすることによってこれを行うことができます

const userAns = [{"id":1,"text":"answer1","employee":[{"name":"John","weight":3,"gender":"male"},{"name":"Sally","weight":4,"gender":"female"}]},{"id":2,"text":"answer2","employee":[{"name":"John","weight":6,"gender":"male"},{"name":"Sally","weight":3,"gender":"female"}]}]; 
 

 
const result = [... 
 
    [].concat(...userAns.map(({ employee }) => employee)) // combine all employees to a single array 
 
    .reduce((m, o) => { // reduce similar employees to a single object in a Map, and combine weight 
 
    // if the name object doesn't exists create a new one by cloning the object, and assigning weight: 0 
 
    m.has(o.name) || m.set(o.name, Object.assign({}, o, { weight: 0 })); 
 
    
 
    m.get(o.name).weight += o.weight; // add the current weight to the name object 
 
    
 
    return m; 
 
    }, new Map()) 
 
    .values()]; // get the Map values, and spread to convert to array 
 
    
 
console.log(result);

+0

このソリューションは私のために働き、forループを削除し、残りのコードと整列します。 – user990951

1

を取得しようとしていますどのようにあなたがlodash find方法を利用することができますし、次にpluckあなたはオブジェクトから欲しいと値を取得するオブジェクトのeはvaluesを使用して

var userAns = [{ 
 
    id: 1, 
 
    text: "answer1", 
 
    employee: [{ 
 
     name: "John", 
 
     weight: 3, 
 
     gender: "male" 
 
     }, 
 
     { 
 
     name: "Sally", 
 
     weight: 4, 
 
     gender: "female" 
 
     } 
 
    ] 
 
    }, 
 
    { 
 
    id: 2, 
 
    text: "answer2", 
 
    employee: [{ 
 
     name: "John", 
 
     weight: 6, 
 
     gender: "male" 
 
     }, 
 
     { 
 
     name: "Sally", 
 
     weight: 3, 
 
     gender: "female" 
 
     } 
 
    ] 
 
    } 
 
]; 
 

 
var scores = []; 
 
for (var i = 0; i < userAns.length; i++) { 
 
    for (var j = 0; j < userAns[i].employee.length; j++) { 
 
    scores.push(userAns[i].employee[j]); 
 
    } 
 
} 
 

 
var result = _(scores) 
 
    .map('name') 
 
    .uniq() 
 
    .map(function(key) { 
 
    return { 
 
     name: key, 
 
     gender: _.values(_.pick(_.find(scores, (d) => d.name == key),'gender'))[0], 
 
     score: _(scores).filter({ 
 
     name: key 
 
     }).sumBy('weight') 
 
    }; 
 
    }) 
 
    .value(); 
 

 
console.log(result);
<script src="https://cdn.jsdelivr.net/lodash/4.14.1/lodash.min.js"></script>

1

あなたはlodashせずにこれを実現することができ、最終的な結果オブジェクトのジェンダーキーに割り当てます。 array#reduceを使用して、最初にemployeeの配列をそれぞれuserAnsの内側に累積し、次にarray#reduceを使用してweightを合計することができます。その後、lodashを使用してObject.values()

var userAns = [{ id: 1, text: "answer1", employee: [{ name: "John", weight: 3, gender: "male" }, { name: "Sally", weight: 4, gender: "female" } ] }, { id: 2, text: "answer2", employee: [{ name: "John", weight: 6, gender: "male" }, { name: "Sally", weight:3, gender: "female" }]}]; 
 

 
var result = userAns 
 
       .reduce((r,o) => r.concat(o.employee),[]) 
 
       .reduce((r,o) => { 
 
        if(r[o.name]) 
 
         r[o.name].weight += o.weight; 
 
        else 
 
        r[o.name] = o; 
 
        return r; 
 
       },{}); 
 
       
 
var output = Object.values(result); 
 
console.log(output);

+0

クレアが必要な場合あなたのコードでは、lodashを使用している場合、lodashの '_.reduce'と' _.value'の 'Object.values'で' reduce'を置き換える方が良いでしょう。 –

+0

私はlodashが本当に清潔でエレガントな機能を提供することに同意します。しかし、賢い人は、ロダッシュを使わなくてもコードをきれいにすることができます。 –

+1

私はあなたに同意しています。プロジェクトマネージャーと私のプロジェクトマネージャーとの会話があったのは、私たちのプロジェクトのどこにいても、単にコードをもっとシンプルで読みやすいものと思ったら使用していますが、ロダッシュを使う必要があると言いました。私たちのための標準。コードや他のチームメイトの構造ではなく、問題に依存していると思います。 –

0

。まず、あなたが

return { 
    name: key, 
    score: user.sumBy('weight'), 
    gender: user.get('[0]').gender 
}; 

を以下のように、そこから得点の合計と性別を抽出することができます

var user = _(scores).filter({ 
    name: key 
}); 

以下のようにmap内のユーザーを取得

var userAns = [{ 
 
    id: 1, 
 
    text: "answer1", 
 
    employee: [{ 
 
    name: "John", 
 
    weight: 3, 
 
    gender: "male" 
 
    }, { 
 
    name: "Sally", 
 
    weight: 4, 
 
    gender: "female" 
 
    }] 
 
}, { 
 
    id: 2, 
 
    text: "answer2", 
 
    employee: [{ 
 
    name: "John", 
 
    weight: 6, 
 
    gender: "male" 
 
    }, { 
 
    name: "Sally", 
 
    weight: 3, 
 
    gender: "female" 
 
    }] 
 
}]; 
 

 
var scores = []; 
 
for (var i = 0; i < userAns.length; i++) { 
 
    for (var j = 0; j < userAns[i].employee.length; j++) { 
 
    scores.push(userAns[i].employee[j]); 
 
    } 
 
} 
 

 

 
var result = _(scores) 
 
    .map('name') 
 
    .uniq() 
 
    .map(function(key) { 
 
    var user = _(scores).filter({ 
 
     name: key 
 
    }); 
 
    return { 
 
     name: key, 
 
     score: user.sumBy('weight'), 
 
     gender: user.get('[0]').gender 
 
    }; 
 
    }) 
 
    .value(); 
 

 
console.log(result);
<script src="https://cdn.jsdelivr.net/lodash/4.14.1/lodash.min.js"></script>

以下の修正スニペットを見つけてください。
関連する問題