简体   繁体   English

在Redux Reducer中更新和重新定位数组中的对象

[英]Update and reposition object in array in Redux reducer

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 is an array of objects like above. 状态是上述对象的数组。 When the app updates an object, the object should flow up to the first position. 当应用更新对象时,该对象应流动到第一个位置。

Eg let's say that we take the second object above (with the primary key 12 ), and copy and update it so it looks like this: 例如,假设我们将上面的第二个对象(主键为12 ),然后复制并更新它,如下所示:

{12: {a: 45, b: 33}}

And now we want to insert it to the array with the following result: 现在,我们要将其插入到数组中,结果如下:

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

I understand how to update an object in an immutable fashion, but I cannot get my head around how to accomplish the above. 我了解如何以一成不变的方式更新对象,但是我无法理解如何完成上述任务。

something like this perhaps? 像这样的东西?

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

You could use something like 您可以使用类似

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

What this does is filtering the state between the items you want to update and the rest, apply the update to the selection and concat the untouched items to them. 这是在要更新的项目和其余项目之间的状态之间进行过滤,将更新应用于所选内容,并将未触及的项目连接到它们。

Below another example on with the same idea which illustrates that you can perform the update on more than one item : 在另一个具有相同想法的示例下,该示例说明您可以对多个项目执行更新:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM