Сравните два массива и вставьте пустые значения

#javascript #arrays #reactjs

Вопрос:

У меня есть два массива:

 var array1 = [{id: 1, time: 100}, {id: 2, time: 200}, {id: 3, time: 300}];
var array2 = [{id: 1, time: 100}, {id: 3, time: 300}];
 

И я хотел бы, чтобы array2 был изменен на

 var array2 = [{id: 1, time: 100}, null, {id: 3, time: 300}];
 

Вопрос в том, как я могу сравнить два массива и посмотреть на их время, а затем вставить null в отсутствующие места для каждого массива.

Любая помощь будет признательна!

Комментарии:

1. Всегда ли массивы отсортированы и id уникальны?

2. Нет, идентификатор не уникален, и да, они отсортированы по времени.

3. есть ли что-то уникальное, по крайней мере, как время? или вы хотите получить полное сравнение объектов?

4. Да, время будет уникальным, и оно никогда не будет дублироваться в массиве.

5. почему этот вопрос заслуживает повышенного внимания? нет кода и нет идеи, как решить этот вопрос …?

Ответ №1:

 const arr1 = [{id: 1, time: 100}, {id: 2, time: 200}, {id: 3, time: 300}];
const arr2 = [{id: 1, time: 100}, {id: 3, time: 300}, {id: 3, time: 400}];

const uniqueTimes = [...arr1, ...arr2]
  .filter((e, i, a) => a.findIndex(x => x.time === e.time) === i)

const res1 = uniqueTimes.map(e => 
  arr1.find(x => x.time === e.time) ?? null
)

const res2 = uniqueTimes.map(e => 
  arr2.find(x => x.time === e.time) ?? null
)

console.log(res1)
console.log(res2) 

Комментарии:

1. Я думаю, что подсказка OPs работает как в обоих массивах. В обоих массивах может быть разное время

2. Совершенно верно. Он должен был бы иметь возможность работать в обоих направлениях, например, если бы у array2 был объект со свойством времени 400, он должен был бы передавать значение null в array1.

Ответ №2:

Ваш пример немного вводит в заблуждение. В вашем описании приглашения говорится, что записи могут отсутствовать в обоих массивах, верно? В моем примере в массиве 2 отсутствует 200, а в массиве 1-400

 var array1 = [{ id: 1, time: 100 }, { id: 2, time: 200 }, { id: 3, time: 300 }];
var array2 = [{ id: 1, time: 100 }, { id: 3, time: 300 }, { id: 1, time: 400 }];
// get all possible times, sort them
const allSortedTimes = array1.map(({ time }) => time).concat(array2.map(({ time }) => time)).sort((a, b) => a - b)
// only use uniq times
const allUniqTimes = [...new Set(allSortedTimes)]
// now that we have all the possible times,
// we go over each array and check to see if that time exists
const insertedArray1 = allUniqTimes.map((uniqTime) => {
  return array1.find(({ time }) => time === uniqTime) ?? null
})

const insertedArray2 = allUniqTimes.map((uniqTime) => {
  return array2.find(({time}) => time === uniqTime) ?? null
})
console.log(insertedArray1)
console.log(insertedArray2) 

Комментарии:

1. Да, я приношу извинения за вводящий в заблуждение вопрос. Я вижу, что вы сделали, собрав все возможные времена, отсортировав их, а затем сопоставив с этим. Большое вам спасибо за помощь!

Ответ №3:

Вот один из способов сделать это.

 var array1 = [{
  id: 1,
  time: 100
}, {
  id: 2,
  time: 200
}, {
  id: 3,
  time: 300
}];
var array2 = [{
  id: 1,
  time: 100
}, {
  id: 3,
  time: 300
}];

const fixArray = (a, maxTime) => {
  let inc = 100,
    start = inc,
    tmp = [];
  // first make sure we have it in order
  //a = a.sort((a, b) => (a.time < b.time) ? -1 : 1)
  while (start < maxTime) {
    let t = a.filter(el => el.time === start)
    if (t.length === 0) tmp.push(null);
    else tmp.push(t[0])
    start  = inc;
  }
  return tmp
}

array2 = fixArray(array2, 1000);
console.log(array2) 

Ответ №4:

 const getKey=(id,time)=>id "_" time //Provides unique key based on object values


var array1 = [{id: 1, time: 100}, {id: 2, time: 200}, {id: 3, time: 300}];
var array2 = [{id: 0, time: 5},{id: 1, time: 100},{id: 11, time: 250}, {id: 3, time: 300},{id: 5, time: 500}];

let keysOfArray1=[]//array1 unique keys
let keysOfArray2=[]//array2 unique keys

array1.map(item=>{
    keysOfArray1.push(getKey(item.id,item.time)); // collects array1 unique keys
    return item
}).concat(array2.map(item=>{//concat array2 values with array1
    keysOfArray2.push(getKey(item.id,item.time)) // collects array2 unique keys
    return item
})).sort((a,b)=>a.time-b.time || a.id-b.id).reduce((prev,current)=>{ //Sort by time amp; then Id
    let keyName=getKey(current.id,current.time)
    if(!prev.includes(keyName)){// To consider all objects only once
        array1[prev.length]=keysOfArray1.includes(keyName)?current:null
        array2[prev.length]=keysOfArray2.includes(keyName)?current:null
        prev.push(keyName)
    }
    return prev
},[])


console.log(array1);
console.log(array2);