在JavaScript中合并两个数组的值

时间:2022-03-21 12:20:29

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:

我的数据系列从1980年开始,到1986年结束。我的任务是将所有缺失的值输入到数组中;在我的情况下,最后的数组应该是:

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.

我通过两个步骤来实现这个任务。首先,我创建了一个长度为7个元素的空数组(对于1980 - 1986年),并使用值{"year": $CURRENT_YEAR, "weight": 0}初始化每个元素。然后循环数据数组,在空数组中查找当前年度的索引,并用当前值替换年份和权重字段。我的代码粘贴在下面。

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}
}

4 个解决方案

#1


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;

最好使用.map()来完成这项工作。此外,如果您有一个较大的输入数组,那么最好首先设置一个散列(lut),例如;

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);

#2


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++;
}

#3


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);
}

#4


1  

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

您可以使用find()和while循环来实现这一点。

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().

您还可以首先使用map()获取年份数组,然后使用indexOf()的while循环。

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)

#1


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;

最好使用.map()来完成这项工作。此外,如果您有一个较大的输入数组,那么最好首先设置一个散列(lut),例如;

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);

#2


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++;
}

#3


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);
}

#4


1  

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

您可以使用find()和while循环来实现这一点。

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().

您还可以首先使用map()获取年份数组,然后使用indexOf()的while循环。

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)