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