我正在尝试合并任何重复键上的数据,但也会重写数据对象。
我正在尝试合并值数组,具体取决于每个对象是否具有相同的“时间”。之后,我想将项目中的每个值与名称配对。
我认为最简单的显示方式是通过我希望转换的原始数据,所以我想改造以下内容;
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"]
}]
我一直在尝试这个this问题来帮助我做到这一点但是我没有走得太远。我似乎无法解决检查未作为数组输出的第一个项目的问题。
非常感谢任何帮助!
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)
答案 0 :(得分: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 :(得分: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);

答案 2 :(得分:0)
编写一个按时间分组的函数可能会有所帮助:
const result =
groupBy(data, entry => entry.time).entries().map(
([time, entries]) => {
const group = {time};
entries.forEach(entry => {
group[entry.name] = entry.item;
});
return group;
}
);
然后你可以:
public static class InputManager
{
// #region #endregion tags are a nice way of blockifying code in VS.
#region Fields
// Store current and previous states for comparison.
private static MouseState previousMouseState;
private static MouseState currentMouseState;
// Some keyboard states for later use.
private static KeyboardState previousKeyboardState;
private static KeyboardState currentKeyboardState;
#endregion
#region Update
// Update the states so that they contain the right data.
public static void Update()
{
previousMouseState = currentMouseState;
currentMouseState = Mouse.GetState();
previousKeyboardState = currentKeyboardState;
currentKeyboardState = Keyboard.GetState();
}
#endregion
#region Mouse Methods
public static Rectangle GetMouseBounds(bool currentState)
{
// Return a 1x1 squre representing the mouse click's bounding box.
if (currentState)
return new Rectangle(currentMouseState.X, currentMouseState.Y, 1, 1);
else
return new Rectangle(previousMouseState.X, previousMouseState.Y, 1, 1);
}
public static bool GetIsMouseButtonUp(MouseButton btn, bool currentState)
{
// Simply returns whether the button state is released or not.
if (currentState)
switch (btn)
{
case MouseButton.Left:
return currentMouseState.LeftButton == ButtonState.Released;
case MouseButton.Middle:
return currentMouseState.MiddleButton == ButtonState.Released;
case MouseButton.Right:
return currentMouseState.RightButton == ButtonState.Released;
}
else
switch (btn)
{
case MouseButton.Left:
return previousMouseState.LeftButton == ButtonState.Released;
case MouseButton.Middle:
return previousMouseState.MiddleButton == ButtonState.Released;
case MouseButton.Right:
return previousMouseState.RightButton == ButtonState.Released;
}
return false;
}
public static bool GetIsMouseButtonDown(MouseButton btn, bool currentState)
{
// This will just call the method above and negate.
return !GetIsMouseButtonUp(btn, currentState);
}
#endregion
#region Keyboard Methods
// TODO: Keyboard input stuff goes here.
#endregion
}
// A simple enum for any mouse buttons - could just pass mouseState.ButtonState instead
public enum MouseButton
{
Left,
Middle,
Right
}
答案 3 :(得分: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);
答案 4 :(得分: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);
答案 5 :(得分: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 })
})