按Javascript对象键+数组分组

时间:2017-01-09 18:27:27

标签: javascript arrays underscore.js

我正在尝试使用下划线将我的对象数组分组到一个较小的列表中:

with your_table(c1, c2) as (
  select 'AA', '1, 2, 3' union all
  select 'BB', '1, 2' 
)
select c1, a.q.value('.', 'varchar(100)') c2
from (select
    c1,
    cast('<q>' + replace(c2, ', ', '</q><q>') + '</q>' as XML) c2
from your_table)t
cross apply c2.nodes('/q') as a(q);

哪个会有点接近,但是它缺少一些Vals。我希望基于键连接'vals'数组。

with your_table(c1, c2) as (
  select 'AA', '1, 2, 3' from dual union all
  select 'BB', '1, 2' from dual
)
select t.c1, x.column_value c2
from your_table t
cross join table(
    cast (
        multiset(
            select regexp_substr(t.c2, '[^, ]+', 1, level)
            from dual
            connect by level <= regexp_count(t.c2, ', ') + 1 
        ) as sys.odcivarchar2list
    )
) x;

http://jsfiddle.net/77gL11c9/1/

3 个答案:

答案 0 :(得分:2)

list.reduce(function (memo, v) {
  if (memo[v.Region]) {
    memo[v.Region] = memo[v.Region].concat(v.Vals)
  } else {
    memo[v.Region] = v.Vals.slice()
  }
  return memo
}, {})

输出将如下所示:

{
  A: [ 7, "H", 40, "VH" ],
  B: [40, "H", 24, "VH" ],
  C: [ 4, "VH" ]
}

答案 1 :(得分:1)

使用带有引用对象的本机JavaScript Array#reduce方法来保存索引。

var list = [
  { Region: 'A', Vals: [ 7, 'H' ] },
  { Region: 'B', Vals: [ 40, 'H' ] },
  { Region: 'B', Vals: [ 24, 'VH' ] },
  { Region: 'C', Vals: [ 4, 'VH' ] },
  { Region: 'A',Vals: [ 40, 'VH' ] }
];


// object for refering index
var ref = {};

// iterate over the array
var res = list.reduce(function(arr, v) {
      // check property defined if not define and push
      // value to array
      if (!(v.Region in ref)) {
        ref[v.Region] = arr.length;
        arr.push({Region: v.Region, Vals: v.Vals});
      // if index already defined then push values
      } else{
        [].push.apply(arr[ref[v.Region]].Vals, v.Vals);
      }
    // return the array reference
    return arr;
  // set initial value as empty array
}, []);

console.log(res);

更新:如果您要生成一个对象,其中Region值为属性名称,Vals值为其值,则执行以下操作。

var list = [
  { Region: 'A', Vals: [ 7, 'H' ] },
  { Region: 'B', Vals: [ 40, 'H' ] },
  { Region: 'B', Vals: [ 24, 'VH' ] },
  { Region: 'C', Vals: [ 4, 'VH' ] },
  { Region: 'A',Vals: [ 40, 'VH' ] }
];


// iterate over the array
var res = list.reduce(function(obj, v) {
  // define the property as an array if not 
  // already defined
  obj[v.Region] = obj[v.Region] || [];
  
  // push all values to array
  [].push.apply(obj[v.Region], v.Vals);
  
  // return the object reference
  return obj;
  
  // set initial value as an empty object
}, {});

console.log(res);

答案 2 :(得分:0)

这将产生您正在寻找的确切输出。

//first build an object with Region properties, and add the Vals to each of those properties

var tempList = {}; 
for (var i=0; i < list.length; i++) {
  if (!(list[i].Region in tempList)) {
    tempList[list[i].Region] = [];
  }
  Array.prototype.push.apply(tempList[list[i].Region],list[i].Vals);
}

//then format this as an array of objects    
var groupedList = [];
for (var region in tempList) {
    groupedList.push({Region:region, Vals: tempList[region]});
}

list = groupedList;

在上面的代码之后,以下内容将成立:

list = [
  { Region: 'A', Vals: [ 7, 'H', 40, 'VH' ] },
  { Region: 'B', Vals: [ 40, 'H',  24, 'VH' ] },
  { Region: 'B', Vals: [ 24, 'VH' ] },
  { Region: 'C', Vals: [ 4, 'VH' ] }
];