Create array from json with exceptions to the value

时间:2019-04-16 22:10:55

标签: javascript jquery arrays json dictionary

let me show you some working code I have here:

Example that works

[
    {
        "actual_time":"11:00:00",
        "length":"30"
    },
    {
        "actual_time":"13:05:00",
        "length":"40"
    }
]

var extracted_times = dataObj.map(o => o.actual_time.split(':').slice(0, 2).map(Number));

The result would be like this:

[
    [11, 0],
    [13, 5]
]

So that works well.


My question:

Here is the problem I'm having. But what if I have this:

[
    {
        "actual_time":"11:00:00",
        "length":"30"
    },
    {
        "actual_time":"13:05:00-00:40:00",
        "length":"40"
    }
]

As you can see, there is a dash in the middle of two times: 13:05:00-00:40:00. How can I make it so that if there is a dash -, then do something like this:

I want the final result to be like this:

[
    [11, 0],
    { from: [13, 0], to: [0, 40] }
]

how can I get it to be like that? Thanks!

4 个答案:

答案 0 :(得分:3)

var extracted_times = dataObj.map(function(obj){
    // match all instances of the time string "hh:mm:ss"
    var times = obj.actual_time.match(/\d\d:\d\d:\d\d/g)
                 // do your thing with the numbers
                   .map(t=>t.split(':').slice(0,2).map(Number));
    // if there is only one, then return it
    if(times.length == 1)
        return times[0];
    // if there are two, then return the object
    return { from: times[0], to: times[1] };
});

答案 1 :(得分:2)

Solution:

You can use a ternary expression along with your map function to iterate and determine if the String contains a (-) hyphen character by using String.prototype.includes.


--- What's a Ternary?

A ternary expression takes an expression and performs differently if true or false. It looks like this:

(expression) ? if_expression_true : if_expression_false;

The base of our ternary expression is whether or not a -(hyphen) exists in the string, so our improved syntax would look something like this:

(string.includes("-")) ? process_with_hyphen : process_without_hyphen

Code Solution:

data.map(({actual_time: s }) => s.includes("-") ? 
    ([from, to] = s.split("-").map(p), {from,to}) : 
    p(s), 
    p = s => s.split(':').slice(0, 2).map(Number), from = to = null);

Code Explanation:

  • We map over our data, supplying 4 things to the map function
    • our function that's used with map. (Note: we use destructuring to pull actual_time from the object and store it in the variable s) This function returns one of two things.
      • If the - (hyphen) character is included
        • Split the String at the hyphen
        • map over the created array with the normal process
        • return an Object with from and to properties
          • The property values are [0] and [1] of the array respectively
      • If the - (hyphen) character is not included
        • perform the normal process on the String
        • return the resulting array
    • three variables
      • p : A function that performs our normal processing on a string and returns the Array. This is what you had in your original question.
      • from and to: variables we set to null. We do this because in a ternary statement you cannot make variable declarations, only variable assignments. There are multiple ways to do this, but I think this is the cleanest.

Code With Comments

//map over data and store "actual_time" in "s"
data.map(({actual_time: s }) => 

// determine if "s" includes a hyphen
    s.includes("-") ? 

// if it does
// split at hyphen and process the resulting array with map
// we use destructuring to assign the first and second values of the new array
// to "from" and "to"
// return a new object with "from" and "to" properties 
// using the from and to variables
    ([from, to] = s.split("-").map(p), {from,to}) : 

// if it does not
// process the String as normal
    p(s), 

// our declared variables for the function:
    p = s => s.split(':').slice(0, 2).map(Number), 
    from = to = null);

Working Code Snippet:

let dataObj = [{
    "actual_time": "11:00:00",
    "length": "30"
  },
  {
    "actual_time": "13:05:00-00:40:00",
    "length": "40"
  }
],

extract = data => data.map(({actual_time: s }) => s.includes("-") ? 
    ([from, to] = s.split("-").map(p), {from,to}) : 
    p(s), 
    p = s => s.split(':').slice(0, 2).map(Number), from = to = null);


let extracted_times = extract(dataObj);

console.log(extracted_times);

答案 2 :(得分:1)

Just check to see if the actual_time has - in it first. If not, then use your original algorithm; otherwise, split it by -, and apply the algorithm to both split pieces:

const arr = [
    {
        "actual_time":"11:00:00",
        "length":"30"
    },
    {
        "actual_time":"13:05:00-00:40:00",
        "length":"40"
    }
];

const timeToNum = time => time.split(':').slice(0, 2).map(Number);
const output = arr.map(({ actual_time }) => {
  if (!actual_time.includes('-')) {
    return timeToNum(actual_time);
  }
  const [fromTime, toTime] = actual_time.split('-');
  return {
    from: timeToNum(fromTime),
    to: timeToNum(toTime)
  };
});
console.log(output);

答案 3 :(得分:0)

I suggest you extract the logic you currently have in the map into a named function and write your logic there.

Something in this spirit

function parseTime(timeString) {
  if (timeString.indexOf("-") === -1) {
    // no dash, return what you currently have
  } else {
    // dash found, split on dash and format the object
  }
}

dataObj.map(parseTime)

The logic used in the if branch can probably be reused to parse from and to in the else branch, so you might want to make it a function as well.

On another note, I would rather return something like this, which should probably be easier to work with.

[
    { from: [11, 0] },
    { from: [13, 0], to: [0, 40] }
]
相关问题