如何转换js数组以按日制作

时间:2019-02-06 17:48:13

标签: javascript arrays

const arr = [
    {"datetime":"2018/8/5","value":85,"type":"A"},
    {"datetime":"2018/8/10","value":7,"type":"B"},
    {"datetime":"2018/8/10","value":73,"type":"A"}
];

您可以在代码段中看到一个数组。我的问题是我需要每天检查一些东西:

  1. A value > 60B value > 6的每一天都要做某事。
  2. A value <= 60B value <= 6时再执行其他操作。

我不知道如何使用当前的数组结构执行此检查,因为循环中的每一步都是不同的日子。我想同时比较一天中的所有值。

是否可以将数组转换成这样?这样我就可以每天比较一天了。

const arr = [
    {"datetime":"2018/8/5","valueA":85,"valueB":undefined},
    {"datetime":"2018/8/10","valueB":7,"valueA":73}
];

谢谢!

5 个答案:

答案 0 :(得分:1)

您可以将日期组简化为一个对象。然后只需在该对象中设置适当的值。最后,您的数组将位于分组对象的Object.keys()中。

[您可能会从注释中推测出,由于不能保证对象键和值,因此不能保证最终数组的顺序。如果您按日期对原始数据进行了排序,那么您应该在问题中这样说,因为如果有保证的顺序,将会有更有效的方法]。

const arr = [{"datetime":"2018/8/5","value":85,"type":"A"},{"datetime":"2018/8/10","value":7,"type":"B"},{"datetime":"2018/8/10","value":73,"type":"A"}];

let groups = arr.reduce((obj, {datetime, value, type}) => {
  if (!obj[datetime]) obj[datetime] = {datetime, valueA:undefined, valueB:undefined} 
  let currentKey = type == 'A' ? "valueA" : "valueB"
  obj[datetime][currentKey] = value
  return obj
},{})

let newArr = Object.values(groups)
console.log(newArr)

答案 1 :(得分:1)

这将按照OP的要求转换数组,并遵守顺序。

const arr = [{"datetime":"2018/8/5","value":85,"type":"A"},
{"datetime":"2018/8/10","value":7,"type":"B"},
{"datetime":"2018/8/10","value":73,"type":"A"}];

var daysArr = []

arr.map(function(day){

    var keyName = 'value'+day.type
    var found = false
    var dayObj = {}

    for (var i=0; i < daysArr.length; i++) {
        if (daysArr[i].datetime === day.datetime) {
            daysArr[i][keyName] = day.value;
            found = true
            break
        }
    }

    if (!found) {
        dayObj = {"datetime":day.datetime,valueA:undefined,valueB:undefined}
        dayObj[keyName] = day.value
        daysArr.push(dayObj)
    }

})

console.log(daysArr);

答案 2 :(得分:0)

一种解决方案可能是使用reduce()。请注意,如果未定义key,则会返回undefined(这在控制台的第二条日志中得到了说明),因此除非您愿意,否则我认为多余的定义,例如"value-B": undefined为其分配另一个默认值。

警告:如评论所述,您应该注意,最终结果的顺序可能不会保留。

const arr = [
  {"datetime":"2018/8/5","value":85,"type":"A"},
  {"datetime":"2018/8/10","value":7,"type":"B"},
  {"datetime":"2018/8/10","value":73,"type":"A"}
];

let res = arr.reduce((acc, {datetime, value, type: type}) =>
{
    acc[datetime] = acc[datetime] || {};
    Object.assign(acc[datetime], {datetime, [`value-${type}`]: value});
    return acc;
}, {});

console.log(Object.values(res));
console.log(Object.values(res)[0]["value-B"]);

答案 3 :(得分:0)

您可以这样做:

<html>
<head>
<meta charset="UTF-8"></meta>
<script type="text/javascript">
const arr = [{"datetime":"2018/8/5","value":85,"type":"A"},
{"datetime":"2018/8/10","value":7,"type":"B"},
{"datetime":"2018/8/10","value":73,"type":"A"}];

var new_arr = group_items(arr)
console.log(new_arr)

function group_items(arr)
{
    var ret_arr = []
    for(var x=0;x<arr.length;x++)
    {
        var cur_date = arr[x].datetime
        var pos = lookup_date(cur_date, ret_arr)

        var obj = {}
        obj.datetime = cur_date
        if(pos != false)
        {
            //add to existing item

            if(arr[x].type == 'A')
            {
                ret_arr[pos].valueA = arr[x].value
            }
            else if(arr[x].type == 'B')
            {
                ret_arr[pos].valueB = arr[x].value
            }

        }
        else{
            if(arr[x].type == 'A')
            {
                obj.valueA = arr[x].value
            }
            else if(arr[x].type == 'B')
            {
                obj.valueB = arr[x].value
            }
            ret_arr.push(obj)
        }

    }

    return ret_arr
}

function lookup_date(date, arr)
{
    /*
        returns the position in arr of date
    */
    var retval = false
    for(var x=0;x<arr.length;x++)
    {
        if(arr[x].datetime == date)
        {
            retval = x
            break
        }
    }

    return retval
}
</script>
</head>
<body>
</body>

答案 4 :(得分:0)

如果不需要最终数组以与原始数组相同的顺序包含日期时间,则可以制作一个将日期时间映射到相应值的对象,然后使用Object.values获得最终值数组。这种方法不能保证顺序,因为对象是无序的数据结构:

const arr = [
  {"datetime":"2018/8/5","value":85,"type":"A"},
  {"datetime":"2018/8/10","value":7,"type":"B"},
  {"datetime":"2018/8/10","value":73,"type":"A"}
];

const values_by_date = { };
arr.forEach( ({ datetime, type, value }) =>
  values_by_date[ datetime ] = { 
    datetime/*, valueA: undefined, valueB: undefined*/,
    ...values_by_date[ datetime ], [`value${type}`]: value 
  }
);

const result = Object.values( values_by_date );
console.log( result );

如果您需要最终数组以与原始数组相同的顺序包含日期时间,并且原始数组已经按日期时间排序,则可以像这样通过一次遍历:

const arr = [
  {"datetime":"2018/8/5","value":85,"type":"A"},
  {"datetime":"2018/8/10","value":7,"type":"B"},
  {"datetime":"2018/8/10","value":73,"type":"A"}
];

const result = arr.reduce( ({ result, datetime: prev }, { datetime, type, value }) => {
  if ( datetime !== prev )
    result.push( { datetime/*, valueA: undefined, valueB: undefined*/ } );
  Object.assign( result[ result.length - 1 ], { [`value${type}`]: value } );
  return { result, datetime };
}, { result: [] } ).result;

console.log( result );

注意:如果希望生成的对象包括缺少值的属性,则可以在任一摘录中取消注释/*, valueA: undefined, valueB: undefined*/