根据它的元素改进数组划分

时间:2018-05-30 10:22:13

标签: javascript arrays angularjs

我想根据它的元素将数组分成两个数组 例如,如果我将此数组作为输入

[{id:1,name:"item1_g1"},{id:2,name:"item2_g2"},{id:3,name:"item3_g1"},{id:2,name:"item4_g2"}]

输出应该是两个这样的数组

第一个数组:

[{id:1,name:"item1_g1"},{id:3,name:"item3_g1"}]

第二个数组:

[{id:2,name:"item2_g2"},{id:2,name:"item4_g2"}]

因为我只需要根据属性name

对元素进行分组

我正在使用angularjs而且我已经尝试过这段代码

var values = [{
  id: 1,
  name: "item1_g1"
}, {
  id: 2,
  name: "item2_g2"
}, {
  id: 3,
  name: "item3_g1"
}, {
  id: 2,
  name: "item4_g2"
}];
var group1 = values.filter(function(item) {
  return (item.name.includes('g1'));
});
var group2 = values.filter(function(item) {
  return (item.name.includes('g2'));
});
console.log(group1, group2)

但我不喜欢这个解决方案,因为如果我有一个沉重的数组,那么我需要循环n次以提取n个不利于性能的数组

有没有办法在一个循环中完成所有这些?

4 个答案:

答案 0 :(得分:2)

只需执行一次数组,使用条件来决定项目应放入哪个数组。例如:

var values = [
  { id: 1, name: "item1_g1" }, 
  { id: 2, name: "item2_g2" }, 
  { id: 3, name: "item3_g1" }, 
  { id: 2, name: "item4_g2" }
];

const [group1, group2] = values.reduce((groups, el) => {
   groups[1^el.name.includes('g1')].push(el);  
   return groups;
}, [[], []]);
  
console.log(group1, group2);

您可以创建一个更通用的分组函数,它接受两个参数 - 排序和谓词函数(返回索引)的项数组。但这会有点罗嗦:

function groupBy(arr, indexer) {
  return arr.reduce((groups, el) => {
    const index = indexer(el);
    groups[index] = groups[index] || [];
    groups[index].push(el);
    return groups;
  }, []);
}

答案 1 :(得分:1)

您只能使用Array.prototype.reduce()String.prototype.slice()

结合使用一次

代码示例:

const values = [{id: 1,name: "item1_g1"}, {id: 2,name: "item2_g2"}, {id: 3,name: "item3_g1"}, {id: 2,name: "item4_g2"}];
const groups = values.reduce((a, c) => (a[c.name.slice(-2)].push(c), a), {g1: [], g2: []});

console.log(groups);

答案 2 :(得分:0)

您可以在一个循环中执行此操作,如下所示:

var values = [{
  id: 1,
  name: "item1_g1"
}, {
  id: 2,
  name: "item2_g2"
}, {
  id: 3,
  name: "item3_g1"
}, {
  id: 2,
  name: "item4_g2"
}];
let group1 = [];
let group2 = [];
values.forEach( item => {
    if(item.name.includes('g1')){
       group1.push(item);
    } else {
       group2.push(item);
    }
})
console.log(group1)
console.log(group2)

答案 3 :(得分:0)

// I would do this the old fashioned way. 
// iterate over values and add them to a map with same group id
// this way you won't need to worry about how many groups you have


var groups = {};
for(i=0;i<values.length;i++){
    var groupNum = values[i].name.substring(values[i].name.indexOf('_g') + 2);
    if(groups[groupNum]){
        groups[groupNum].push(values[i]);
    }
    else {
        groups[groupNum] = [values[i]];
    }
}

console.log(groups);
{
  "1": [
    {
      "id": 1,
      "name": "item1_g1"
    },
    {
      "id": 3,
      "name": "item3_g1"
    }
  ],
  "2": [
    {
      "id": 2,
      "name": "item2_g2"
    },
    {
      "id": 2,
      "name": "item4_g2"
    }
  ]
}"