const state = [
{10: {a: 22, b: 33}},
{12: {a: 20, b: 33}},
{15: {a: 22, b: 34}},
{5: {a: 21, b: 30}},
{9: {a: 29, b: 33}},
]
State - это массив объектов, как указано выше. Когда приложение обновляет объект, объект должен перетекать в первую позицию.
Например, предположим, что мы берем второй объект выше (с основным ключом 12
) и копируем и обновляем его так, чтобы он выглядел следующим образом:
{12: {a: 45, b: 33}}
И теперь мы хотим вставить его в массив со следующим результатом:
const state = [
{12: {a: 45, b: 33}},
{10: {a: 22, b: 33}},
{15: {a: 22, b: 34}},
{5: {a: 21, b: 30}},
{9: {a: 29, b: 33}},
]
Я понимаю, как обновлять объект неизменно, но я не могу понять, как это сделать.
Вы можете использовать что-то вроде
// an update function, here it just adds a new key
// to the object
const update = (x) => ({
...x,
hello: "world"
});
// a filter factory
const withId = (id) => (item) => Boolean(item[id]); // item with specific ids
const withoutId = (id) => (item) => !Boolean(item[id]); // others
const state = [
{10: {a: 22, b: 33}},
{12: {a: 20, b: 33}},
{15: {a: 22, b: 34}},
{5: {a: 21, b: 30}},
{9: {a: 29, b: 33}},
];
const id = 5;
const newState = state
.filter(withId(id))
.map(update)
.concat(state.filter(withoutId(id)));
console.log(JSON.stringify(newState, null, 4));
Это означает, что фильтрация состояния между элементами, которые вы хотите обновить, и остальными, применить обновление к выбору и согласовать нетронутые элементы для них.
Ниже приведен другой пример с той же идеей, которая иллюстрирует, что вы можете выполнить обновление более чем для одного элемента:
const markAsDone = (todo) => ({
...todo,
done: true
});
const isInGroup = (group) => (todo) => todo.group === group;
const not = (predicate) => (x) => !predicate(x);
const isWork = isInGroup("work");
const notWork = not(isWork);
const state = [
{
todo: "go shopping",
group: "life"
},
{
todo: "go work",
group: "work",
},
{
todo: "go sleep",
group: "life"
}
];
// get work related todos, mark as done and
// append to todo list
const newState = state
.filter(notWork)
.concat(state
.filter(isWork)
.map(markAsDone));
console.log(JSON.stringify(newState, null, 4));
map
filter
и concat
также создают новые массивы. Логика в этом скрипте состоит в том, чтобы отфильтровать нужные элементы, обновить их неизменным образом и сопоставить результаты с остальными.
что-то вроде этого возможно?
const state = [
{10: {a: 22, b: 33}},
{12: {a: 20, b: 33}},
{15: {a: 22, b: 34}},
{5: {a: 21, b: 30}},
{9: {a: 29, b: 33}},
]
// find the numerical index of the object with the specified "key"
function findIndexOfKey(array, key){
return array.findIndex(function(el){return key in el});
}
// modify object and move to front
function editObjectAndMoveToFront(array, key, updatedValues){
// find index of object with key, for use in splicing
var index = findIndexOfKey(array, key);
// create the updated version of the specified object
var originalObject = array[index];
var originalObjectValue = originalObject[key];
var editedObject = {};
editedObject[key] = Object.assign({}, originalObjectValue, updatedValues)
// here is the new state, with the updated object at the front
var newArray = [
editedObject,
...array.slice(0, index),
...array.slice(index + 1)
]
return newArray
}
const newState = editObjectAndMoveToFront(state, 12, {a: 45, b: 33})
console.log(newState);