admin管理员组

文章数量:1323348

I have an array of objects, and I have to split it by duplicate values on index property. For a sample array of objects like the next one:

[
  {index: 0, value: 3},
  {index: 0, value: 3},
  {index: 0, value: 3},
  {index: 1, value: 3},
  {index: 1, value: 3},
  {index: 2, value: 3},
  {index: 2, value: 3}
]

The expected result should be:

{
  0: [
    {index: 0, value: 3},
    {index: 0, value: 3},
    {index: 0, value: 3}
  ],
  1: [
    {index: 1, value: 3},
    {index: 1, value: 3}          
  ],
  2: [
    {index: 2, value: 3},
    {index: 2, value: 3}
  ]
}

I have an array of objects, and I have to split it by duplicate values on index property. For a sample array of objects like the next one:

[
  {index: 0, value: 3},
  {index: 0, value: 3},
  {index: 0, value: 3},
  {index: 1, value: 3},
  {index: 1, value: 3},
  {index: 2, value: 3},
  {index: 2, value: 3}
]

The expected result should be:

{
  0: [
    {index: 0, value: 3},
    {index: 0, value: 3},
    {index: 0, value: 3}
  ],
  1: [
    {index: 1, value: 3},
    {index: 1, value: 3}          
  ],
  2: [
    {index: 2, value: 3},
    {index: 2, value: 3}
  ]
}
Share Improve this question edited Oct 17, 2019 at 21:37 Shidersz 17.2k2 gold badges27 silver badges51 bronze badges asked Jan 19, 2019 at 19:12 a8hoka8hok 3081 gold badge3 silver badges12 bronze badges 1
  • You claim you need to split on duplicate values, but it looks like you're splitting on duplicate indices. Also, why bother using an object with ascending numerical keys from 0 to n? An array seems more appropriate for the task. Please clarify your intent and post what you've attempted so far. – ggorlen Commented Jan 19, 2019 at 19:47
Add a ment  | 

4 Answers 4

Reset to default 5

Here you have one solution using reduce() and Object.assign():

const input = [
  {index: 0, value: 3},
  {index: 0, value: 3},
  {index: 0, value: 3},
  {index: 1, value: 3},
  {index: 1, value: 3},
  {index: 2, value: 3},
  {index: 2, value: 3},
  {index: 0, value: 3}
];

let obj = input.reduce((res, curr) =>
{
    if (res[curr.index])
        res[curr.index].push(curr);
    else
        Object.assign(res, {[curr.index]: [curr]});

    return res;
}, {});

console.log(obj);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

The previous example will make groups of all objects with equal index property. However, if you are looking to separate the objects by streaks that have equal indexes you can do this:

const input = [
  {index: 0, value: 3},
  {index: 0, value: 3},
  {index: 0, value: 3},
  {index: 1, value: 3},
  {index: 1, value: 3},
  {index: 2, value: 3},
  {index: 2, value: 3},
  {index: 0, value: 3},
  {index: 0, value: 3},
  {index: 0, value: 3},
  {index: 2, value: 3},
  {index: 2, value: 3}
];

let obj = input.reduce((res, curr) =>
{
    if (curr.index === res.last)
    {
        res.r[res.idx - 1].push(curr);
        return res;
    }

    Object.assign(res.r, {[res.idx]: [curr]});
    res.last = curr.index;
    res.idx++;
    return res;

}, {r: {}, idx: 0, last: null});

console.log(obj.r);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

You can use a simple reduce to get this:

const input=[{index:0,value:3},{index:0,value:3},{index:0,value:3},{index:1,value:3},{index:1,value:3},{index:2,value:3},{index:2,value:3}]

/* If index exists in the accumulator object, use that.
  else, create the index and point to an empty array
  push the item in context to the array
*/
const output = input.reduce((acc, v) => {
  acc[v.index] = acc[v.index] || [];
  acc[v.index].push(v);
  return acc;
}, {});

console.log(output)

Here's a short version:

const input=[{index:0,value:3},{index:0,value:3},{index:0,value:3},{index:1,value:3},{index:1,value:3},{index:2,value:3},{index:2,value:3}]

const output = input.reduce((a,v) => ((a[v.index] = a[v.index] || []).push(v), a), {});

console.log(output)

Do a simple reduce operation:

const data = [{
    index: 0,
    value: 3
  },
  {
    index: 0,
    value: 3
  },
  {
    index: 0,
    value: 3
  },
  {
    index: 1,
    value: 3
  },
  {
    index: 1,
    value: 3
  },
  {
    index: 2,
    value: 3
  }, {
    index: 2,
    value: 3
  }
];

const modified = data.reduce((val, acc) => {
  if (acc[val.index]) {
    acc[val.index].push(val);
  } else {
    acc[val.index] = [{
      index: [val.index],
      value: [val.value]
    }];
  }
  return acc;
}, {});

console.log(modified);

You can use simple for loop

const input = [
    {index: 0, value: 3},
    {index: 0, value: 3},
    {index: 0, value: 3},
    {index: 1, value: 3},
    {index: 1, value: 3},
    {index: 2, value: 3},
    {index: 2, value: 3}
];

const newArray = {}
for(var i of input) {
  if(newArray[i.index]) {
    newArray[i.index].push(i)
  } else {
    newArray[i.index] = [i]
  }
}

console.log(newArray)

本文标签: javascriptHow to split array by duplicate valuesStack Overflow