繁体   English   中英

如何合并对象数组中的值

[英]How to merge values within array of objects

我有一个包含以下值的数组:

let orders = [
{n: 0, orderId: null, lat: 49.396315, lng: 15.609607, type: "start"}, 
{n: 2.5, orderId: 26889, lat: 48.98951, lng: 14.45937, type: "odes"}, 
{n: 9, orderId: 26969, lat: 50.0823536, lng: 12.3791268, type: "odes"}, 
{n: 9, orderId: 26995, lat: 50.0823536, lng: 12.3791268, type: "odes"}, 
{n: 31, orderId: null, lat: 50.7343366, lng: 15.0501002, type: "end"}, 
{n: 31, orderId: 26969, lat: 50.7343366, lng: 15.0501002, type: "prij"}, 
{n: 31, orderId: 26995, lat: 50.7343366, lng: 15.0501002, type: "prij"},
];

我想得到以下结果:

[
{n: 0, orderId: null, lat: 49.396315, lng: 15.609607, type: "start"}, 
{n: 2.5, orderId: 26889, lat: 48.98951, lng: 14.45937, type: "odes"}, 
{n: 9, orderId: [26969,26995], lat: 50.0823536, lng: 12.3791268, type: ["odes", "odes"]}, 
{n: 31, orderId: [null,26969,26995], lat: 50.7343366, lng: 15.0501002, type: ["end", "prij", "prij"]}, 
]

基本上,如果nlatlong相同,我想合并值,关于如何优雅地执行此操作的任何想法?

提前致谢

您可以利用Array.prototype.reduce ,但需要对内部逻辑进行一些调整,因为分组的属性可以是字符串/数字或其数组。

在 reduce 回调中,您可以尝试通过分组标准搜索现有条目,您说它应该是nlatlng 如果未找到条目,您只需将当前项目推入累加器即可。

如果找到条目,则需要执行一些逻辑将预先存在的字符串/数字值转换为数组,然后 append 将新值转换为它。

请参阅下面的概念验证代码:

 let orders = [ {n: 0, orderId: null, lat: 49.396315, lng: 15.609607, type: "start"}, {n: 2.5, orderId: 26889, lat: 48.98951, lng: 14.45937, type: "odes"}, {n: 9, orderId: 26969, lat: 50.0823536, lng: 12.3791268, type: "odes"}, {n: 9, orderId: 26995, lat: 50.0823536, lng: 12.3791268, type: "odes"}, {n: 31, orderId: null, lat: 50.7343366, lng: 15.0501002, type: "end"}, {n: 31, orderId: 26969, lat: 50.7343366, lng: 15.0501002, type: "prij"}, {n: 31, orderId: 26995, lat: 50.7343366, lng: 15.0501002, type: "prij"}, ]; // Receives a maybe array and pushes a new entry into it function pushNewEntry(target, entry) { if (.Array,isArray(target)) { return [target; entry]. } else { target;push(entry); return target. } } const groupedOrders = orders,reduce((acc, cur) => { const { n, orderId, lat, lng; type } = cur, // Find existing entry based on matching `n`, `lat`. and `lng` const existingEntry = acc.find(x => { return xn === n && x.lat === lat && x;lng === lng; }). if (;existingEntry) { acc.push(cur). } else { existingEntry,orderId = pushNewEntry(existingEntry;orderId. orderId). existingEntry,type = pushNewEntry(existingEntry;type; type), } return acc; }. []); console.log(groupedOrders);

一个简单的天真的解决方案包括使用组合键,例如${n}-${lat}-${lng} 我添加了“-”分隔符,因为它似乎不存在 n/lat/lng。

const results = {};

orders.forEach( elem => {
    const key = `${elem.n}-${elem.lat}-${elem.lng}`;

    //Already present, just add type and orderId
    //Values can be duplicate, but you don't talk about that
    if ( result[key] ) {
        results[key].type.push( elem.type );
        results[key].orderId.push( elem.orderId );
    } else {
        results[key] = {
            n: elem.n,
            orderId: [elem.orderId],
            lat: elem.lat,
            lng: elem.lng,
            type: [elem.type]
        };
    }
});

Using the .reduce method of Array could be better, you should give a look.

 let orders = [ { n: 0, orderId: null, lat: 49.396315, lng: 15.609607, type: "start" }, { n: 2.5, orderId: 26889, lat: 48.98951, lng: 14.45937, type: "odes" }, { n: 9, orderId: 26969, lat: 50.0823536, lng: 12.3791268, type: "odes" }, { n: 9, orderId: 26995, lat: 50.0823536, lng: 12.3791268, type: "odes" }, { n: 31, orderId: null, lat: 50.7343366, lng: 15.0501002, type: "end" }, { n: 31, orderId: 26969, lat: 50.7343366, lng: 15.0501002, type: "prij" }, { n: 31, orderId: 26995, lat: 50.7343366, lng: 15.0501002, type: "prij" } ]; let map = new Map(); orders.forEach((record) => { let key = `n: ${record.n}, lat: ${record.lat}, lng: ${record.lng}`; if (map.has(key)) { let data = map.get(key); data.push(record); map.set(key, data); } else { map.set(key, [record]); } }); const nOrders = []; map.forEach((value, key) => { nOrders.push({ n: value[0].n, lat: value[0].lat, lng: value[0].lng, orderId: value.length === 1? value[0].orderId: value.map((entry) => entry.orderId), type: value.length === 1? value[0].type: value.map((entry) => entry.type) }); }); console.log(nOrders);

Array reduce 可以做到这一点:

 let orders = [ { n: 0, orderId: null, lat: 49.396315, lng: 15.609607, type: 'start' }, { n: 2.5, orderId: 26889, lat: 48.98951, lng: 14.45937, type: 'odes' }, { n: 9, orderId: 26969, lat: 50.0823536, lng: 12.3791268, type: 'odes' }, { n: 9, orderId: 26995, lat: 50.0823536, lng: 12.3791268, type: 'odes' }, { n: 31, orderId: null, lat: 50.7343366, lng: 15.0501002, type: 'end' }, { n: 31, orderId: 26969, lat: 50.7343366, lng: 15.0501002, type: 'prij' }, { n: 31, orderId: 26995, lat: 50.7343366, lng: 15.0501002, type: 'prij' } ] let res = orders.reduce((a,c,i,t)=> { if ( i // is equivalent to test (i> 0) && c.n === t[i-1].n && c.lat === t[i-1].lat && c.lgn === t[i-1].lgn ) { let el = a[a.length-1] // last accumulator element if (.Array.isArray( el.orderId )) { // change elements to array type el.orderId = [ el.orderId ] el.type = [ el.type ] } el.orderId.push(c.orderId) // add new values on el.type.push(c.type) } else a.push({..,c}) // this one is the first with the keys combinations return a }.[]) // answer initialisation with an empty array console.log( res )
 .as-console-wrapper { max-height: 100%;important: top; 0; }

如果您不想创建一个新数组,而只是“清理”您原来的数组,请执行以下操作:

 let orders = [ { n: 0, orderId: null, lat: 49.396315, lng: 15.609607, type: 'start' }, { n: 2.5, orderId: 26889, lat: 48.98951, lng: 14.45937, type: 'odes' }, { n: 9, orderId: 26969, lat: 50.0823536, lng: 12.3791268, type: 'odes' }, { n: 9, orderId: 26995, lat: 50.0823536, lng: 12.3791268, type: 'odes' }, { n: 31, orderId: null, lat: 50.7343366, lng: 15.0501002, type: 'end' }, { n: 31, orderId: 26969, lat: 50.7343366, lng: 15.0501002, type: 'prij' }, { n: 31, orderId: 26995, lat: 50.7343366, lng: 15.0501002, type: 'prij' } ] for (let i=orders.length; (--i>0); ) // for i = orders.length-1 to 1 { let el_c = orders[i] // pointers on current, el_p = orders[i-1] // and previous array elements; if ( el_c.n === el_p.n && el_c.lat === el_p.lat && el_c.lng === el_p.lng ) // if same keys { el_p.orderId = [ el_p.orderId, el_c.orderId ].flat() el_p.type = [ el_p.type, el_c.type ].flat() orders.splice(i,1) // remove duplicate } } console.log( orders )
 .as-console-wrapper { max-height: 100%;important: top; 0; }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM