使用typescript循环遍历json中的可能数组

时间:2018-03-15 13:20:01

标签: javascript arrays json typescript

询问如何在打字稿中循环数组。我的问题有点不同所以我先解释一下。

我有一个json,看起来像这样:

{
    "forename": "Maria",
    "colors": [
      {
        "name": "blue",
        "price": 10
      },
      {
        "name": "yellow",
        "price": 12
      }
    ],
    "items": [
      {
        "name": "sword",
        "price": 20
      }
    ],
    "specialPowers": [
      {
        "name": "telekinesis",
        "price": 34
      }
    ]
  },
  {
    "forename": "Peter",
    "colors": [
      {
        "name": "blue",
        "price": 10
      }
    ],
    "items": [
      {
        "name": "hat",
        "price": 22
      },
      {
        "name": "hammer",
        "price": 27
      }
    ]
  }

  // some more persons

正如你所看到的,我的人可以拥有颜色,物品或特殊功能等阵列。但是一个人也可以没有。正如你所看到的,Maria拥有阵列specialPowers,但Peter没有。

我需要一个功能来检查一个人是否有这些阵列中的一个,如果是这样,我必须将其价格加总。所以我想要一个人拥有的所有东西的总价。

目前我有三个功能基本上是这样的:

getTotalOfColors(person) {
    let total = 0;
    if(person.colors)
      for (let color of person.colors) {
        total = total + color.price;
      }
    return total;
  }

getTotalOfItems(person) {
    let total = 0;
    if(person.items)
      for (let item of person.items) {
        total = total + item.price;
      }
    return total;
  }

 // SAME FUNCTION FOR SPECIALPOWERS

我基本上有三次相同的功能。唯一的区别是,我在另一个数组中循环。但这些功能都是一样的。他们首先检查一下,如果这个人有阵列,那么他们循环通过这个数组来将价格加到总数中。

最后我的问题:有没有办法在一个功能中完成所有这些?因为他们基本上都在做同样的事情,我不想要冗余的代码。我的想法是循环遍历所有数组,同时检查该人是否有数组,如果是,则将其价格加到总数中。

我认为该功能看起来像这样:

getTotal(person) {
        let total = 0;
        for (let possibleArray of possibleArrays){
          if(person.possibleArray )
            for (let var of person.possibleArray ) {
              total = total + var.price;
            }
          }
        return total;
      }
像这样,我会有一个普遍的"函数,但为此我必须有一个可能的数组数组,如下所示: possibleArrays = [colors,items,specialPowers] 我该如何实现这一目标?我的代码应该如何以及在哪里制作这个数组?或者是否有更好的解决方案来解决这个问题?

3 个答案:

答案 0 :(得分:1)

我创建了一个似乎可以解决这个问题的函数:

query <- " select RESPONDENT as Respondent,RESPONSE_DATE 
    as Date,
    MAX(CASE
    WHEN QUESTION_ID = '18' AND RESPONSE_ID ='5' THEN 'Very Satisfied'
    WHEN QUESTION_ID = '18' AND RESPONSE_ID ='4' THEN 'Satisfied'
    WHEN QUESTION_ID = '18' AND RESPONSE_ID ='3' THEN 'Neutral'
    WHEN QUESTION_ID = '18' AND RESPONSE_ID ='2' THEN 'Dissatisfied'
    WHEN QUESTION_ID = '18' AND RESPONSE_ID ='1' THEN 'Very Dissatisfied' 
    ELSE NULL END) AS \"How was our service looks based on your last meal?\"
    from surveytable
    group by 1,2"
cat(query)

<强>演示:

&#13;
&#13;
function totalPrice(data) {
  let total = 0;
  for (person of data) {                  //Go through the array of people
    for (prop in person) {                //Go through every property of the person
      if (Array.isArray(person[prop])) {  //If this property is an array
        for (element of person[prop]) {   //Go through this array
                                          //Check if `price` is a Number and
                                          //add it to the total
          if (!isNaN(element.price)) total += element.price;
        }
      }
    }
  }

  return total;
}
&#13;
&#13;
&#13;

答案 1 :(得分:1)

您可以使用函数reduce和函数includes来选择所需的目标。

var inputData = [{    "forename": "Maria",    "colors": [{        "name": "blue",        "price": 10      },      {        "name": "yellow",        "price": 12      }    ],    "items": [{      "name": "sword",      "price": 20    }],    "specialPowers": [{      "name": "telekinesis",      "price": 34    }]  },  {    "forename": "Peter",    "colors": [{      "name": "blue",      "price": 10    }],    "items": [{        "name": "hat",        "price": 22      },      {        "name": "hammer",        "price": 27      }    ]  }];

function totalize(possibleArrays, data) {
  return data.reduce((a, c) => {
    return a + Object.keys(c).reduce((ia, k) => {
      if (possibleArrays.includes(k)) c[k].forEach(p => ia += p.price);
      return ia;
    }, 0);    
  }, 0);
}

var total = totalize(["colors", "items", "specialPowers"], inputData);

console.log(total);

答案 2 :(得分:1)

这样的事情也应该这样做,我只是在控制台中记录了结果,但你可以用它们做你想做的事情:

const getSum = (person, prop) => {
    let total = 0;
    if(person[prop])
      for (let value of person[prop]) {
        total = total + value.price;
      }
    return total;
}

const props = ['colors', 'items', 'specialPowers']

console.log(data.map(person => props.map(prop => getSum(person, prop))));

修改

我没有得到你想要一次为一个人总结你所有的属性,这个代码是我绝对会想要的:

const sum = (a, b) => a + b;

const props = ['colors', 'items', 'specialPowers'] 

data.map(person => 
    props.map(prop =>
        (person[prop] || [])
            .map(({price}) => price)
            .reduce(sum, 0)
    ).reduce(sum, 0)
)

如果你想总结所有人的总价:

data.map(person => 
    props.map(prop =>
        (person[prop] || [])
            .map(({price}) => price)
            .reduce(sum, 0)
    ).reduce(sum, 0)
).reduce(sum, 0)