0

我每天都在创建数据,并且正在处理以下响应数据......

{
  tipster: {
    name: "Gallita FC",
    description: "TEST",
    picks: [{
      date: "Friday, February 18th 2022",
      data: [{
        title: "yesterday",
        description: "TEST",
        date: "Friday, February 18th 2022",
        category: "NHL",
        pickImageUrl: "https://res.cloudinary.com/creaciones-inteligentes-roy/image/upload/v1644455039/Captura_de_Pantalla_2022-02-09_a_la_s_18.59.43_voy1pj.png",
      }],
    }, {
      date: "Saturday, February 19th 2022",
      data: [{
        title: "today",
        description: "TEST",
        date: "Saturday, February 19th 2022",
        category: "NHL",
        pickImageUrl: "https://res.cloudinary.com/creaciones-inteligentes-roy/image/upload/v1644455039/Captura_de_Pantalla_2022-02-09_a_la_s_18.59.43_voy1pj.png",
      }],
    }],
    imageUrl: "https://res.cloudinary.com/sports-master/image/upload/v1644649610/27ADF778-454B-4DB7-88B7-DC98202E2736_utb7xw.png",
    bannerUrl: "https://scontent.fmex34-1.fna.fbcdn.net/v/t1.6435-9/167022015_1317341031983063_7337313589197318410_n.jpg?_nc_cat=111&ccb=1-5&_nc_sid=a26aad&_nc_ohc=5ctqP2nFf7IAX94PNSO&_nc_ht=scontent.fmex34-1.fna&oh=00_AT_TzRHhhV73ji7wzW2X1u27TOU8TNlObwtp0ILc0DzC1Q&oe=62207F2C",
    id: "62075e5a13a43ace611fe5bd",
  },
}

tipster.picks数组中,我需要data在最后一个匹配项上附加一个附加data项。匹配可能是 where data.titleequals "today"

到目前为止我想出的代码并没有导致正确的结果......

const newPick = {
  title,
  description,
  date,
  category,
  pickImageUrl,
};    

const tipsterUpdate = {
  ...req.body,
  picks: [...tipster.picks, tipster.picks.slice(-(1)[0], newPick)],
};

我正在使用扩展运算符,因为我需要维护旧数据并且只在数据数组上添加一个新对象。

我真的很感谢这里的一点帮助。谢谢你。

4

2 回答 2

0

引用 OP

我正在使用扩展运算符,因为我需要维护旧数据并且只在数据数组上添加一个新对象。

由于传播语法只创建一个浅拷贝,因此拷贝的任何嵌套级别仍然是一个引用,因此有被变异的危险,我建议通过一次深度克隆structuredClone(对于尚不支持此 Web 的环境有 polyfills- API 方法)。

至于一种通用方法,它在(或者)具有匹配条件的最后一个数据之后(或者甚至在每个条件匹配数据项之后)插入一个新数据项,需要一个提供的函数

  • 深度克隆的响应数据对象的tipster.picks引用,
  • 要插入的新数据项,
  • 实现匹配数据项条件的回调函数。

在第一步中,将收集条件匹配的所有数据项的列表。第二步是插入任务,可以适应可能不断变化的需求......

function insertDataItemAfterLastMatchingCondition(picks, item, condition) {
  // collect a list of all data items where `condition` matches.
  const matchList = picks
    .reduce((matches, pickItem) => {

      const { data } = pickItem;
      const index = data.findIndex(condition);

      if (index >= 0) {
        matches.push({ array: data, index });
      }
      return matches;

    }, []);

  // insert new item excusivley after the last matching data item.
  const { array, index } = matchList.at(-1) ?? {};
  if (Array.isArray(array)) {

    array.splice((index + 1), 0, item);
  }
  // // insert new item (copy) after every matching data item.
  //
  // matchList.forEach(({ array, index }) =>
  //   array.splice((index + 1), 0, {...item})
  // );
}


const responseData = {tipster:{name:"Gallita FC",description:"TEST",picks:[{date:"Friday, February 18th 2022",data:[{title:"yesterday",description:"TEST",date:"Friday, February 18th 2022",category:"NHL",pickImageUrl:"https://res.cloudinary.com/creaciones-inteligentes-roy/image/upload/v1644455039/Captura_de_Pantalla_2022-02-09_a_la_s_18.59.43_voy1pj.png"}]},{date:"Saturday, February 19th 2022",data:[{title:"today",description:"TEST",date:"Saturday, February 19th 2022",category:"NHL",pickImageUrl:"https://res.cloudinary.com/creaciones-inteligentes-roy/image/upload/v1644455039/Captura_de_Pantalla_2022-02-09_a_la_s_18.59.43_voy1pj.png"}]}],imageUrl:"https://res.cloudinary.com/sports-master/image/upload/v1644649610/27ADF778-454B-4DB7-88B7-DC98202E2736_utb7xw.png",bannerUrl:"https://scontent.fmex34-1.fna.fbcdn.net/v/t1.6435-9/167022015_1317341031983063_7337313589197318410_n.jpg?_nc_cat=111&ccb=1-5&_nc_sid=a26aad&_nc_ohc=5ctqP2nFf7IAX94PNSO&_nc_ht=scontent.fmex34-1.fna&oh=00_AT_TzRHhhV73ji7wzW2X1u27TOU8TNlObwtp0ILc0DzC1Q&oe=62207F2C",id:"62075e5a13a43ace611fe5bd"}};

const responseClone = (typeof structuredClone === 'function')
  && structuredClone(responseData)
  || JSON.parse(JSON.stringify(responseData)); // fallback

const newData = {
  title: 'tomoorow',
  description: 'TEST',
  date: 'Sunday, February 20th 2022',
  category: 'NHL',
  pickImageUrl: 'https://res.cloudinary.com/creaciones-inteligentes-roy/image/upload/v1644455039/Captura_de_Pantalla_2022-02-09_a_la_s_18.59.43_voy1pj.png',
};


insertDataItemAfterLastMatchingCondition(
  responseClone.tipster.picks,
  newData,
  data => data.title === 'today',
); 
console.log({ responseData, responseClone });
.as-console-wrapper { min-height: 100%!important; top: 0; }

于 2022-02-19T10:55:50.367 回答
0

从对象中的所有其他内容中解构出picks数组tipster,然后构建一个tipster包含更新picks数组的新对象。

const data={tipster:{name:"Gallita FC",description:"TEST",picks:[{date:"Friday, February 18th 2022",data:[{title:"yesterday",description:"TEST",date:"Friday, February 18th 2022",category:"NHL",pickImageUrl:"https://res.cloudinary.com/creaciones-inteligentes-roy/image/upload/v1644455039/Captura_de_Pantalla_2022-02-09_a_la_s_18.59.43_voy1pj.png"}]},{date:"Saturday, February 19th 2022",data:[{title:"today",description:"TEST",date:"Saturday, February 19th 2022",category:"NHL",pickImageUrl:"https://res.cloudinary.com/creaciones-inteligentes-roy/image/upload/v1644455039/Captura_de_Pantalla_2022-02-09_a_la_s_18.59.43_voy1pj.png"}]}],imageUrl:"https://res.cloudinary.com/sports-master/image/upload/v1644649610/27ADF778-454B-4DB7-88B7-DC98202E2736_utb7xw.png",bannerUrl:"https://scontent.fmex34-1.fna.fbcdn.net/v/t1.6435-9/167022015_1317341031983063_7337313589197318410_n.jpg?_nc_cat=111&ccb=1-5&_nc_sid=a26aad&_nc_ohc=5ctqP2nFf7IAX94PNSO&_nc_ht=scontent.fmex34-1.fna&oh=00_AT_TzRHhhV73ji7wzW2X1u27TOU8TNlObwtp0ILc0DzC1Q&oe=62207F2C",id:"62075e5a13a43ace611fe5bd"}};

const newPick = {
  title: 'Bob',
  description: 'Bob does it again',
  date: new Date(),
  category: 'Bob',
  pickImageUrl: 'bobImage',
};

// Accept data, the new pick, and a search
// (in this case "today")
function addNewPick(data, newPick, search) {

  // Grab the picks, and then everything else
  // from the tipster object
  const { tipster: { picks, ...rest } } = data;

  // `find` the index of the array containing the search text
  const index = picks.findIndex(pick => {
    return pick.data.some(obj => {
      return obj.title === search;
    });
  });

  // Add the new pick to the "today" array
  picks[index].data.push(newPick);

  // Return a new tipster object with
  // the updated picks
  return {
    tipster: { ...rest, picks }
  };

}

const out = addNewPick(data, newPick, 'today');

console.log(out);

于 2022-02-19T10:14:21.917 回答