如何使用通用键合并属性数组

时间:2019-03-29 14:39:35

标签: javascript underscore.js

如何使用下划线js实现以下结果?

当前结果:

[
{Stats: "Number of virus", "Dec-2018": "1"},
{Stats: "Number of alerts", "Dec-2018": "2"},
{Stats: "Number of incidents", "Dec-2018": "1"},
{Stats: "Vulnerabilities", "Dec-2018": "6"},
{Stats: "Number of virus", "Nov-2018": "4"},
{Stats: "Number of alerts", "Nov-2018": "6"},
{Stats: "Number of incidents", "Nov-2018": "2"},
{Stats: "Vulnerabilities", "Nov-2018": "8"},
{Stats: "Number of virus", "Oct-2018": "2"},
{Stats: "Number of alerts", "Oct-2018": "2"},
{Stats: "Number of incidents", "Oct-2018": "5"},
{Stats: "Vulnerabilities", "Oct-2018": "2"},
]

预期结果:

[
{Stats: "Number of virus", Dec-2018: "1", "Nov-2018": "4", Oct-2018: "2"},
{Stats: "Number of alerts", Dec-2018: "2","Nov-2018": "6", Oct-2018: "2"},
{Stats: "Number of incidents", Dec-2018: "1", "Nov-2018": "2", Oct-2018: "5"},
{Stats: "Vulnerabilities", Dec-2018: "6", "Nov-2018": "8", Oct-2018: "2"}
]

3 个答案:

答案 0 :(得分:0)

您可以通过以下过程来实现。首先,使用Stats函数创建一个具有唯一indexBy()值的对象。之后,对于每个数据元素,使用相同的Stats值扩展该元素。就是这样!

var data = [
{Stats: "Number of virus", "Dec-2018": "1"},
{Stats: "Number of alerts", "Dec-2018": "2"},
{Stats: "Number of incidents", "Dec-2018": "1"},
{Stats: "Vulnerabilities", "Dec-2018": "6"},
{Stats: "Number of virus", "Nov-2018": "4"},
{Stats: "Number of alerts", "Nov-2018": "6"},
{Stats: "Number of incidents", "Nov-2018": "2"},
{Stats: "Vulnerabilities", "Nov-2018": "8"},
{Stats: "Number of virus", "Oct-2018": "2"},
{Stats: "Number of alerts", "Oct-2018": "2"},
{Stats: "Number of incidents", "Oct-2018": "5"},
{Stats: "Vulnerabilities", "Oct-2018": "2"},
]

var indexed = _.indexBy(data, 'Stats');

_.each(data, function(elem) {
  var object = indexed[elem.Stats];
  if (object) _.extend(object, elem);
});

var result = Object.values(indexed);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

答案 1 :(得分:0)

您可以像这样使用reduceObject.values()

select 
  current_day.ShippedDate,
  case 
    when current_day.row = 1 then current_day.UnitsInStock
    else next_day.Quantity + next_day.DaySales
  end as DayEnd,
  current_day.Quantity + current_day.DaySales as DayStart,
  current_day.Quantity,
  current_day.DaySales,
  case 
    when current_day.row = 1 then current_day.UnitsInStock - current_day.DaySales
    else next_day.Quantity + next_day.DaySales - current_day.DaySales
  end as ReorderUnits
from (
  select
    row_number() over (order by ShippedDate desc) as row,
    SOMETHING_SHOULD_GO_HERE as DaySales,
    -- ^^^ or if it's dependent on some calculation between days,
    -- calculate it in your select above
    Quantity,
    ShippedDate,
    UnitsInStock
  from dummy
) as current_day
left join (
  select
    row_number() over (order by ShippedDate desc) - 1 as row,
    SOMETHING_SHOULD_GO_HERE as DaySales, 
    Quantity
  from dummy
) as next_day
on next_day.row = current_day.row

答案 2 :(得分:0)

您可以使用findIndexreduce

const data = [
{Stats: "Number of virus", "Dec-2018": "1"},
{Stats: "Number of alerts", "Dec-2018": "2"},
{Stats: "Number of incidents", "Dec-2018": "1"},
{Stats: "Vulnerabilities", "Dec-2018": "6"},
{Stats: "Number of virus", "Nov-2018": "4"},
{Stats: "Number of alerts", "Nov-2018": "6"},
{Stats: "Number of incidents", "Nov-2018": "2"},
{Stats: "Vulnerabilities", "Nov-2018": "8"},
{Stats: "Number of virus", "Oct-2018": "2"},
{Stats: "Number of alerts", "Oct-2018": "2"},
{Stats: "Number of incidents", "Oct-2018": "5"},
{Stats: "Vulnerabilities", "Oct-2018": "2"},
]

const res = data.reduce((all, {
  Stats,
  ...rest
}) => {

  let found = all.findIndex(o => Stats === o.Stats);

  if (found > -1 ) {
    all[found] = { ...all[found],
      ...rest
    }
  } else {
    all.push({ ...{
        Stats,
        ...rest
      }
    })

  }
  return all
}, [])

console.log(res)