2

I have an array which looks like:

var data = [{"year":[1981],"weight":[3]},
            {"year":[1982],"weight":[4]},
            {"year":[1985],"weight":[7]}]

My data series starts with year 1980 and ends with year 1986. My task is to input all missing values into the array; in my case the final array should be:

var data = [{"year":[1980],"weight":[0]},
            {"year":[1981],"weight":[3]},
            {"year":[1982],"weight":[4]},
            {"year":[1983],"weight":[0]},
            {"year":[1984],"weight":[0]},
            {"year":[1985],"weight":[7]},
            {"year":[1986],"weight":[0]}]

I implemented this task in two steps. First I created an empty array with length of seven elements (for years 1980 - 1986) and initialize each element with value {"year": $CURRENT_YEAR, "weight": 0}. Then I loop through data array, find index of current year in the empty array and replace year and weight fields with current values. My code is pasted below.

I wonder if the code could be rewritten in a more elegant way.

// Create empty array
var my_array = []
var length = 7

// 1st step
year = 1980
for (var i = 0; i < length; i++) {
  my_array.push({"year": year, "weight": 0});
  year++
}

// 2nd step
for (var j = 0; j < data.length; j++) {
  curr_year = data[j]["year"][0];
  curr_weight = data[j]["weight"][0]
  var index = my_array.findIndex(function(item, i) {return item.year === curr_year})
  my_array[index] = {"year": curr_year, "weight": curr_weight}
}
3
  • Why are your values in arrays, like [1981] and [3]? Do you intend to store more values in them? I see your code does not store the values as arrays in the first step, but it does partly in the second. So one of the two is wrong. Your code code can't work like that. Commented Nov 4, 2016 at 13:45
  • "I wonder if the code could be rewritten in a more elegant way." - if this is your question, should this not be posted to codereview? Commented Nov 4, 2016 at 13:56
  • Well, the code obviously is not doing what the OP is asking for, so I think the question really should be rephrased to "This doesn't work because I get this result (....), and not the desired result (...). What did I do wrong?". Not for CodeReview. Commented Nov 4, 2016 at 14:02

4 Answers 4

2

It's best to do this job by .map() Besides if you have a large input array it might be wise to set up a hash (lut) in the first place such as;

var data = [{"year":[1981],"weight":[3]},
            {"year":[1982],"weight":[4]},
            {"year":[1985],"weight":[7]}],
     lut = data.reduce((p,c) => p[c.year[0]] ? p : (p[c.year[0]] = c, p), {});
   range = [1980,1986],
  result = Array(range[1]-range[0] + 1).fill()
                                       .map((_,i) => lut[i+range[0]] ? lut[i+range[0]] : {year: [i+range[0]], weight: [0]});
console.log(result);

Sign up to request clarification or add additional context in comments.

Comments

1

You can combine the 2 loops and do both steps in one loop

// Create empty array
var my_array = []
var length = 7


year = 1980
for (var i = 0; i < length; i++) {
    // check if there is data for the year
    var index = data.findIndex(function(item, i) {return item.year === year});
    if(index > -1){ //if there is data, use it
        my_array.push({"year": data[index]["year"][0], "weight": data[index]["weight"][0]});
    }else{ //put in default data
       my_array.push({"year": year, "weight": 0});
    }
    year++;
}

Comments

1

Find index of element in array each time is bad performance for large data. I can suggest the following algorithm:

// Create empty object and fill it with values where keys are years
var years = {};
data.forEach(item => {
    years[item.year[0]] = item.weight[0];
});

// Result array with all years
var result = [];
var startYear = 1980;
var endYear = 1986;

// Generate our result array
for (var i = startYear; i <= endYear; i++) {

    // If property for given year (i) exists in "years" object then add it to "result" array
    // in other case add default object with weight 0
    var o = years[i] ? { year: [i], weight: [years[i]] } : { year: [i], weight: [0] };
    result.push(o);
}

Comments

1

You could do this with just find() and while loop.

var data = [{"year":[1981],"weight":[3]},{"year":[1982],"weight":[4]},{"year":[1985],"weight":[7]}];
                   
var i = 1980;
var result = [];

while(i <= 1986) {
  var find = data.find(e => e.year[0] == i);
  (find) ? result.push(find) : result.push({year: [i], weight: [0]});
  i++;
}

console.log(result)

You could also first use map() to get array of years and then use while loop with indexOf().

var data = [{"year":[1981],"weight":[3]},{"year":[1982],"weight":[4]},{"year":[1985],"weight":[7]}];
            
var i = 1980;
var result = [];
var years = data.map(e => e.year[0]);

while(i <= 1986) {
  var ind = years.indexOf(i);
  (ind !=  -1) ? result.push(data[ind]) : result.push({year: [i], weight: [0]});
  i++;
}

console.log(result)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.