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

时间:2016-12-13 15:31:53

标签: javascript arrays

我正在尝试合并任何重复键上的数据,但也会重写数据对象。

我正在尝试合并值数组,具体取决于每个对象是否具有相同的“时间”。之后,我想将项目中的每个值与名称配对。

我认为最简单的显示方式是通过我希望转换的原始数据,所以我想改造以下内容;

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)

6 个答案:

答案 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 })
})
相关问题