如何基于重复键合并/组合对象数组?

3

我正在尝试合并任何重复的键上的数据,但同时还要重写数据对象。

我正在尝试根据每个对象是否具有相同的“时间”来合并值数组。之后,我希望将项中的每个值与名称配对。

我认为最容易的方法是通过原始数据来展示我希望转换的内容。因此,我想转换以下内容:

var data = [{
  "item": ["1", "2"],
  "time": "12-15",
  "name": "ben"
}, {
  "item": ["3", "4"],
  "time": "12-15",
  "name": "bill"
}, {
  "item": ["1", "2", "3"],
  "time": "15-18",
  "name": "ben"

}, {
  "item": ["4", "5", "6"],
  "time": "15-18",
  "name": "bill"
}];

进入

var result = [{
  "time": "12-15",
  "ben": ["1", "2"],
  "bill": ["3", "4"]
},
{
  "time": "15-18",
  "ben": ["1", "2", "3"],
  "bill": ["4", "5", "6"]
}]

我一直在尝试解决这个问题来帮助我做这件事,但是我没有进展。我似乎无法解决第一个被检查的项不能作为数组输出的问题。

非常感谢任何帮助!

var data = [{
  "item": ["1", "2"],
  "time": "12-15",
  "name": "ben"
}, {
  "item": ["3", "4"],
  "time": "12-15",
  "name": "bill"
}, {
  "item": ["1", "2", "3"],
  "time": "15-18",
  "name": "ben"

}, {
  "item": ["4", "5", "6"],
  "time": "15-18",
  "name": "bill"

}];



var seen = {};
var result = data.filter(function(entry) {
  var previous;

  // Have we seen this label before?
  if (seen.hasOwnProperty(entry.time)) {

    // Yes, grab it and add this data to it
    previous = seen[entry.time];
    previous.item.push(entry.item);

    // Don't keep this entry, we've merged it into the previous one
    return false;
  }
  //console.log(seen)
  // entry.data probably isn't an array; make it one for consistency
  if (!Array.isArray(entry.item)) {
    entry.item = [entry.item];
  }

  // Remember that we've seen it
  seen[entry.time] = entry;

  // Keep this one, we'll merge any others that match into it
  return true;
});

console.log(result)


在这个任务中,Array.prototype.reduce()Object.keys()Array.prototype.map() 是你的好朋友。 - Redu
6个回答

1
您可以使用哈希表进行分组。

var data = [{ "item": ["1", "2"], "time": "12-15", "name": "ben" }, { "item": ["3", "4"], "time": "12-15", "name": "bill" }, { "item": ["1", "2", "3"], "time": "15-18", "name": "ben" }, { "item": ["4", "5", "6"], "time": "15-18", "name": "bill" }],
    result = [];

data.forEach(function (a) {
    if (!this[a.time]) {
        this[a.time] = { time: a.time };
        result.push(this[a.time]);
    }
    this[a.time][a.name] = (this[a.time][a.name] || []).concat(a.item);
}, Object.create(null));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

或者使用ES6,你可以使用一个 Map

var data = [{ "item": ["1", "2"], "time": "12-15", "name": "ben" }, { "item": ["3", "4"], "time": "12-15", "name": "bill" }, { "item": ["1", "2", "3"], "time": "15-18", "name": "ben" }, { "item": ["4", "5", "6"], "time": "15-18", "name": "bill" }],
    map = new Map,
    result = [];

data.forEach(a => {
    var o = map.get(a.time);
    if (!o) {
        o = { time: a.time };
        map.set(a.time, o);
        result.push(o);
    }
    o[a.name] = (o[a.name] || []).concat(a.item);
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }


1
我希望您采用创建两个函数并返回合并数据的新对象的方法,这样可以避免对原始对象进行变异。
注意:这使用ES6语法,但您可以轻松将此代码转换为ES5。

const data = [{
  "item": ["1", "2"],
  "time": "12-15",
  "name": "ben"
}, {
  "item": ["3", "4"],
  "time": "12-15",
  "name": "bill"
}, {
  "item": ["1", "2", "3"],
  "time": "15-18",
  "name": "ben"

}, {
  "item": ["4", "5", "6"],
  "time": "15-18",
  "name": "bill"

}];

// Get a list of unique times
const getTimes = data => data.reduce((a, c) => {
  if (!a.includes(c.time)) {
    a.push(c.time);
  }      
  
  return a;
}, []);

// Merge the data into a single list using the times list as index
const mergeData = (data, times) => times.map(time => {
  const obj = {};
  obj.time = time;
  
  data.forEach(record => {
    if (record.time === time) {
      obj[record.name] = record.item;
    }
  });
  
  return obj;
});

const times = getTimes(data);
const result = mergeData(data, times);

console.log(result);


0
你可以使用map()和filter()以及类似下面这样的内部循环来完成它:

var data = [{
  "item": ["1", "2"],
  "time": "12-15",
  "name": "ben"
}, {
  "item": ["3", "4"],
  "time": "12-15",
  "name": "bill"
}, {
  "item": ["1", "2", "3"],
  "time": "15-18",
  "name": "ben"
}, {
  "item": ["4", "5", "6"],
  "time": "15-18",
  "name": "bill"
}];

var skel = data.map(x => x.time).filter((x,i,arr) => arr.indexOf(x) === i).map(x => ({"time" : x}));
var result = skel.map(x => {
  data.forEach(y => {
    if(x.time === y.time)
      x[y.name] = y.item;
  })
  return x;
} )
console.log(result);


0
您可以按照以下步骤操作:

var data = [{
  "item": ["1", "2"],
  "time": "12-15",
  "name": "ben"
}, {
  "item": ["3", "4"],
  "time": "12-15",
  "name": "bill"
}, {
  "item": ["1", "2", "3"],
  "time": "15-18",
  "name": "ben"

}, {
  "item": ["4", "5", "6"],
  "time": "15-18",
  "name": "bill"
}],

interim = data.reduce((h,d) => (h[d.time] = h[d.time] ? h[d.time].concat({[d.name]: d.item})
                                                      : [{[d.name]: d.item}],h),{}),
 result = Object.keys(interim)
                .map(k => Object.assign({time: k},...interim[k]));
console.log(result);


0

编写一个按时间分组的函数可能会很有帮助:

class DefaultMap extends Map {
    constructor(defaultConstructor) {
        super();
        this.defaultConstructor = defaultConstructor;
    }

    get(key) {
        if (this.has(key)) {
            return super.get(key);
        }

        const def = this.defaultConstructor();
        this.set(key, def);
        return def;
    }
}

function groupBy(collection, key) {
    const groups = new DefaultMap(() => []);

    for (const item of collection) {
        const itemKey = key(item);
        const group = groups.get(itemKey);

        group.push(item);
    }

    return groups;
}

那么你可以这样做:

const result =
    groupBy(data, entry => entry.time).entries().map(
        ([time, entries]) => {
            const group = {time};

            entries.forEach(entry => {
                group[entry.name] = entry.item;
            });

            return group;
        }
    );

0

试试这个

var timeGroup = _.groupBy(data,"time");

_.mapObject(timeGroup,function(val,key){
var benArray = _.flatten(_.values(_.pick(_.findWhere(val,   {name:"ben"}),"item")));
var billArray = _.flatten(_.values(_.pick(_.findWhere(val,{name:"bill"}),"item")));
console.log({"time" : key,"ben" : benArray , "bill" : billArray })
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接