如何根据除指定属性以外的其他属性将对象附加到数组?

时间:2018-11-09 07:57:58

标签: javascript arrays json

例如,我有一个像这样的对象数组:

[

{
      "waterfallData.PopulationName":"Population 1",
      "Deaths":-2333,
      "Births":8786,
      "open":0,
      "close":6453
   },
   {
      "waterfallData.PopulationName":"Population 2",
      "Deaths":-1000,
      "Births":5000,
      "open":0,
      "close":10453
   },
   {
      "waterfallData.PopulationName":"Population 3",
      "Deaths":-2000,
      "Births":500,
      "open":0,
      "close":8953
   }
]

我想在每个种群之间添加两个(不必是两个,如果有"Extra Births"则是三个)中间物体

[

{
      "waterfallData.PopulationName":"Population 1",
      "Death":-2333,
      "Births":8786,
      "open":0,
      "close":6453
   },
   {
      "Deaths" : -1000,
       "open"   : 6453,
       "close"  : 5453
   },
   {
     "Births" : 5000,
      "open"   : 5453,
      "close   : 10453
   }
   {
      "waterfallData.PopulationName":"Population 2",
      "Deaths":-1000,
      "Births":5000,
      "open":0,
      "close":10453
   },
   {
      "Deaths" : -2000,
      "open"    : 10453,
      "close"   : 8453
   },
   {
      "Births" : 500,
      "open"    : 8453,
      "close"   : 8953
   }
   {
      "waterfallData.PopulationName":"Population 3",
      "Deaths":-2000,
      "Births":500,
      "open":0,
      "close":8953
   }
]

如您所见,我想基于除waterfallData.PopulationNameopenclose属性之外的其他属性来添加对象。然后,我想基于下一个openclose值在每个对象上分配"Deaths""Births"属性。

例如,Population 1以6453开头,然后我添加两个对象,第一个对象采用"Deaths"中的下一个Population 2值,即-1000,然后分配{{1} }属性来自open的先前close属性,而Population 1属性则是通过将分配的close属性与open的值相加来计算的。同样,第二个额外的对象也是如此,我将"Deaths"属性指定为前一个对象的open属性,并将close属性指定为通过添加closeopen的值。

我该如何实现?

2 个答案:

答案 0 :(得分:1)

粗暴..但是有效

var newArr = [];
$x = [{
    "waterfallData.PopulationName":"Population 1",
    "Deaths":-2333,
    "Births":8786,
    "open":0,
    "close":6453
},{
    "waterfallData.PopulationName":"Population 2",
    "Deaths":-1000,
    "Births":5000,
    "open":0,
    "close":10453
},{
    "waterfallData.PopulationName":"Population 3",
    "Deaths":-2000,
    "Births":500,
    "open":0,
    "close":8953
}];
$x.forEach((p,i)=>{
    var current = $x[i]
    newArr.push(current)
    try {
        var next = $x[i+1];
        var start = current.open;
        var end = current.close;
        var states = Object.keys(current).sort().filter((k)=>{return (['waterfallData.PopulationName','open','close'].indexOf(k) < 0)})
        for (var i=0;i<states.length;i++){
            var state = states[i]
            var tempObj = {}
            tempObj[states[i]] = next[states[i]]
            tempObj['open'] = end;
            end += next[states[i]];
            tempObj['close'] = end;
            newArr.push(tempObj)
        }
    } catch (e) {
        return false;
    }
})

代码将查找除WaterfallData.Popu ..外的所有属性,将其打开,关闭并将其视为状态。如果您有10个属性,则除了上述3个之外,将有7个状态。然后,从下一个元素计算这些状态的打开和关闭值,并将其推入新数组newArr。

答案 1 :(得分:0)

我会尝试一下,您可以指定哪些键需要作为额外数据,但原始数据必须具有这些键的值。它将按照提供键的顺序创建其他项:

const data = [{"waterfallData.PopulationName":"Population 1","Deaths":-2333,"Births":8786,"open":0,"close":6453},{"waterfallData.PopulationName":"Population 2","Deaths":-1000,"Births":5000,"open":0,"close":10453},{"waterfallData.PopulationName":"Population 3","Deaths":-2000,"Births":500,"open":0,"close":8953}];

const zip = (arr1, arr2) =>
  [...new Array(Math.max(arr1.length, arr2.length))]
    .map((_, i) => i)
    .map((i) => [arr1[i], arr2[i]]);
const extras = (keys) => ([current, next]) =>
  keys.map((key) => [key, next[key]]).reduce(
    ([result, lastClose], [key, nextValue]) => [
      result.concat({
        [key]: nextValue,
        open: lastClose,
        close: nextValue + lastClose,
      }),
      nextValue + lastClose,
    ],
    [[], current.close],
  )[0];
const withExtras = (keys) => ([current, next]) =>
  !next
    ? [current]
    : [current].concat(extras(keys)([current, next]));
console.log(
  zip(data, data.slice(1)) //having [[current,next],[current,next]...]
    .map(withExtras(['Deaths', 'Births']))
    .flatten(),
);

console.log(
  'diffenrent order different result',
  zip(data, data.slice(1))
    .map(withExtras(['Births', 'Deaths']))
    .flatten(),
);