Javascript: Split array of objects into seperate arrays with dynamic names depending on property value

时光毁灭记忆、已成空白 提交于 2019-12-13 17:14:21

问题


I have an array containing objects. Now I want to slice the array to new arrays containing only those objects matching a certain property value.

Ideally the new array names should be created dynamically.

The original array looks like this:

specificSlotButtonArray = [
  {slotStarttime:"06:00:00", slotTimespan:1},
  {slotStarttime:"09:00:00", slotTimespan:1},
  {slotStarttime:"12:00:00", slotTimespan:2},
  {slotStarttime:"15:00:00", slotTimespan:2},
  {slotStarttime:"18:00:00", slotTimespan:3}
];

The new arrays should look like this:

timespan1 = [
  {slotStarttime:"06:00:00", slotTimespan:1},
  {slotStarttime:"09:00:00", slotTimespan:1}
]

timespan2 = [
  {slotStarttime:"12:00:00", slotTimespan:2},
  {slotStarttime:"15:00:00", slotTimespan:2}
]

timespan3 = [
  {slotStarttime:"18:00:00", slotTimespan:3}
]

If possible, I want to avoid javascript syntax / functions, which are not supported by IE and some other older browsers.

I already tried to work with reduce() and slice(), but did not find a solution.


回答1:


You can simply achieve your desired outcome using reduce, as you can produce an object using reduce, here's an example of how you could do it.

As you can see, it'll check that the relevant property on the object isn't null, if it is, then it's set to an empty array, after this check, it's safe to simply push the relevant values onto the array, like so.

var array = [{
    slotStarttime: "06:00:00",
    slotTimespan: 1
  },
  {
    slotStarttime: "09:00:00",
    slotTimespan: 1
  },
  {
    slotStarttime: "12:00:00",
    slotTimespan: 2
  },
  {
    slotStarttime: "15:00:00",
    slotTimespan: 2
  },
  {
    slotStarttime: "18:00:00",
    slotTimespan: 3
  }
];

var newObject = array.reduce(function(obj, value) {
  var key = `timespan${value.slotTimespan}`;
  if (obj[key] == null) obj[key] = [];

  obj[key].push(value);
  return obj;
}, {});

console.log(newObject);



回答2:


You could reduce the array by taking an object for the part arrays.

var specificSlotButtonArray = [{ slotStarttime: "06:00:00", slotTimespan: 1 }, { slotStarttime: "09:00:00", slotTimespan: 1 }, { slotStarttime: "12:00:00", slotTimespan: 2 }, { slotStarttime: "15:00:00", slotTimespan: 2 }, { slotStarttime: "18:00:00", slotTimespan: 3 }],
    timespan1 = [],
    timespan2 = [],
    timespan3 = [];
    
specificSlotButtonArray.reduce(function (r, o) {
    r[o.slotTimespan].push(o);
    return r;
}, { 1: timespan1, 2: timespan2, 3: timespan3 });

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



回答3:


Use a generic group by key reducer. I will take it from a previous answer of mine. It is an elegant and simple way to generate a function that group your data by a particular key that comes as an argument.

const groupBy = key => (result,current) => {
  const item = Object.assign({},current);
  if (typeof result[current[key]] == 'undefined'){
    result[current[key]] = [item];
  }else{
    result[current[key]].push(item);
  }
  return result;
};

const specificSlotButtonArray = [
  {slotStarttime:"06:00:00", slotTimespan:1},
  {slotStarttime:"09:00:00", slotTimespan:1},
  {slotStarttime:"12:00:00", slotTimespan:2},
  {slotStarttime:"15:00:00", slotTimespan:2},
  {slotStarttime:"18:00:00", slotTimespan:3}
];

const timespan = specificSlotButtonArray.reduce(groupBy('slotTimespan'),{});
console.log(timespan);



回答4:


The following soluce iterates once on specificSlotButtonArray using Array.reduce. This soluce will adapt to any number of slotTimespan.

const specificSlotButtonArray = [{
    slotStarttime: '06:00:00',
    slotTimespan: 1,
  },
  {
    slotStarttime: '09:00:00',
    slotTimespan: 1,
  },
  {
    slotStarttime: '12:00:00',
    slotTimespan: 2,
  },
  {
    slotStarttime: '15:00:00',
    slotTimespan: 2,
  },
  {
    slotStarttime: '18:00:00',
    slotTimespan: 3,
  },
];

// Loop through the array
const splitted = specificSlotButtonArray.reduce((tmp, x) => {
  // Look if we got already an array having the slotTimespan of the current
  // item to treat
  const match = tmp.find(y => y.some(z => z.slotTimespan === x.slotTimespan));

  // If we have such array, push the data into it
  if (match) {
    match.push(x);
  } else {
    // If we don't create a new array
    tmp.push([x]);
  }

  return tmp;
}, []);

console.log(splitted);

If you want to deals with the array straight after the Array.reduce you can use destructuration :

const [
  timespan1,
  timespan2,
  timespan3
] = specificSlotButtonArray.reduce((tmp, x) => {



回答5:


You can use this function to create separate arrays grouped by slotTimespan,

    specificSlotButtonArray = [
        {slotStarttime:"06:00:00", slotTimespan:1},
        {slotStarttime:"09:00:00", slotTimespan:1},
        {slotStarttime:"12:00:00", slotTimespan:2},
        {slotStarttime:"15:00:00", slotTimespan:2},
        {slotStarttime:"18:00:00", slotTimespan:3}
    ];
    
    function groupBy(arr, property) {
        return arr.reduce(function(memo, x) {
            if (!memo[x[property]]) { memo[x[property]] = []; }
            memo[x[property]].push(x);
            return memo;
        }, {});
    }
    
    console.log(groupBy(specificSlotButtonArray, "slotTimespan"));


来源:https://stackoverflow.com/questions/54008878/javascript-split-array-of-objects-into-seperate-arrays-with-dynamic-names-depen

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!