【问题标题】:handling arrays in javascript在javascript中处理数组
【发布时间】:2021-06-26 16:01:44
【问题描述】:

我是 javascript 新手并做出反应 我有一个数据数组如下

const data = [
    {
        folder_name: "folder 002",
        file_name: "anh 1.jpg"
    },
    {
        folder_name: "folder 002",
        file_name: "anh 2.jpg"
    },
    {
        folder_name: "folder 002",
        file_name: "anh 3.jpg"
    },
    {
        folder_name: "folder 002",
        file_name: "anh 4.jpg"
    },
    {
        folder_name: "folder 001",
        file_name: "anh 1.jpg"
    },
    {
        folder_name: "folder 001",
        file_name: "anh 2.jpg"
    },
    {
        folder_name: "folder 001",
        file_name: "anh 3.jpg"
    }
]

请帮我分成这样的数组。 请帮我像这样返回数组 我想要的结果

const images = [
    {
        folder_name: 'folder 001',
        file_name: ['anh 1','anh 2','anh 3']
    },
    {
        folder_name: 'folder 002',
        file_name: ['anh 1','anh 2','anh 3','anh 4']
    }
]

非常感谢

【问题讨论】:

  • 不要将您的数据作为图像发布。使用 JavaScript 语法将其作为文本发布。其次,您应该描述您尝试过的内容以及遇到问题的地方(错误、意外输出、无限循环……)
  • 谢谢我已经完全上传了我的代码,你能帮帮我吗我的问题是我不知道如何拆分数组以获得我帖子中的结果
  • 当你起草你的问题时,有一些说明:(1)总结问题(2)描述你尝试过的东西(3)显示一些代码。你几乎没有做过(1),你没有做过(2)也没有做过(3)。
  • 不好意思,因为是新手,不知道下次会撤掉经验,非常感谢
  • 为什么是“下一次”?请编辑您的问题并添加您尝试过的内容、使用的代码以及发生了什么(错误?无限循环?意外输出?)

标签: javascript arrays reactjs object


【解决方案1】:

短篇:

let result = array.reduce((accumulator,c)=>{

       !accumulator.find(w=>w.folder_name == c.folder_name)?
       accumulator.push({folder_name: c.folder_name, file_name: [c.file_name]}):
       accumulator.find(w=>w.folder_name == c.folder_name).file_name.push(c.file_name)    
        
    return accumulator
},[])

使用Reduce 函数使其简单易读。 reduce 函数迭代第一个参数(它是一个函数)与array 的长度一样多。我们将一个空列表作为第二个参数传递给 Reduce 函数。它也是accumulator 参数。 Reduce 函数在每次迭代中更新列表 a.k.a accumulator。这意味着在每个迭代中减少上一次迭代的 accumulator 的回报。

例如:accumulator.push(5) 将返回一个包含数字 5 作为 array 长度的列表,因为我们在每次迭代中将数字 5 推送到列表中。

参数c是数组中当前正在处理的元素。

例如:Reduce 的第一次迭代在参数c 中给出array[0],第二次迭代给出array[1],以此类推。在这种情况下,c 是一个对象列表。

此外,我们在作为第一个参数传递的函数中使用Conditional Operator。条件运算符是 If-else 语句的简短版本。

!accumulator.find(w=>w.folder_name == c.folder_name)

我们搜索列表accumulator 是否包含与参数c 具有相同键值的对象(这是array 的元素之一 - 取决于迭代的索引)。

如果我们没有找到任何 folder_name 等于 c 的,我们推送一个包含这些值的新对象

accumulator.push({folder_name: c.folder_name, file_name: [c.file_name]})

如果我们找到任何folder_name 等于c 的那个,我们会在find 的帮助下得到这个对象,并为这个对象添加必要的值

accumulator.find(w=>w.folder_name == c.folder_name).file_name.push(c.file_name)
   

总之,在检查accumulator 中的每个c(当前值)并在每次迭代中将必要的值添加到accumulator 之后,我们返回accumulator。它将accumulator 传递给下一次迭代,最后返回accumulator 本身

【讨论】:

  • Woooooooooh 这太小了,请添加一些实现,这对 OP 来说会容易得多! (虽然很好的答案)
  • 感谢您的关心和帮助
【解决方案2】:

const data=[{folder_name:"folder 002",file_name:"anh 1.jpg"},{folder_name:"folder 002",file_name:"anh 2.jpg"},{folder_name:"folder 002",file_name:"anh 3.jpg"},{folder_name:"folder 002",file_name:"anh 4.jpg"},{folder_name:"folder 001",file_name:"anh 1.jpg"},{folder_name:"folder 001",file_name:"anh 2.jpg"},{folder_name:"folder 001",file_name:"anh 3.jpg"}];

// Iterate over the data with `reduce`
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
const out = data.reduce((acc, c) => {

  // Grab the folder_name as the key
  const { folder_name: key, file_name } = c;

  // If the key doesn't exist on the accumulator
  // create a new object with a file_name array
  acc[key] = acc[key] || { folder_name: key, file_name: [] };

  // Push the filename into the new object array
  acc[key].file_name.push(file_name);

  // Return the accumulator
  return acc;
}, {});

// Grab the object values (an array) from the
// returned object
console.log(Object.values(out));

【讨论】:

  • 感谢您的关心和帮助
【解决方案3】:

我不确定这是否是实现这一点的最佳方式。 但它有效!

const input = [
  { folderName: "folder1", fileName: "file11" },
  { folderName: "folder1", fileName: "file12" },
  { folderName: "folder1", fileName: "file13" },
  { folderName: "folder2", fileName: "file21" },
  { folderName: "folder2", fileName: "file22" },
  { folderName: "folder2", fileName: "file23" },
];

const output = [];

const folderNames = [];

input.forEach((item) => {
  if (!folderNames.includes(item.folderName)) folderNames.push(item.folderName);
});
folderNames.forEach((item) => output.push({ folderName: item, fileNames: [] }));

output.forEach((item, index) => {
  const files = input.filter((i) => i.folderName === item.folderName);
  item.fileNames = [...files.map((i) => i.fileName)];
});

console.log(output);

抱歉,您的对象的键发生了一些变化。我试图写一些与您的对象类似的东西。

【讨论】:

  • 非常感谢感谢您的帮助,我解决了问题,祝您生活愉快
【解决方案4】:

您可以通过reducefindIndex 实现此目的:

let ans = data.reduce((cum,x)=>{
  let exists = cum.findIndex((a)=>{
    if(a['folder_name'] == x['folder_name'])
      return true;
  });
  if(exists==-1){
    cum.push({
      folder_name : x['folder_name'],
      file_name : [x['file_name']]
    })
  }
  else{
    cum[exists]['file_name'].push(x['file_name']);
  }
  return cum;
},[]);

Reduce 通过对所有元素应用相同的函数将数组转换为单个值。第二个参数[] 是开始的初始值。 对于数据数组中的每个元素,我正在检查cum 数组中是否存在相应的文件夹元素。 (cum 数组在每次迭代时都会发生变化。)现在,如果是这样,我将推送到该元素属性,否则我将在 cum 数组中推送一个全新的元素。

注意:顺序与您的预期答案不同。您可以使用自定义 sort() 来帮助解决此问题。

【讨论】:

  • 感谢您的关心和帮助
【解决方案5】:

试试这个功能

const splitArray = array => {
  const folders = [];
  let fileName = [];

  for (let i = 0; i < array.length; i++) {
    const folderName = array[i].folder_name;
    const index = folderName[folderName.length - 1] * 1 - 1;
    if (folders[index] === undefined) {
      fileName = [];
    }
    fileName.push(array[i].file_name);
    folders[index] = {};
    folders[index]['folder_name'] = folderName;

    folders[index]['file_name'] = [...fileName];
  }
  return folders;
};

【讨论】:

  • 感谢您的关心和帮助
【解决方案6】:

不确定这是最好的实现,但它可以工作

  const images = [{
    folder_name: "folder 001",
    file_name: "ab",
  },
    {
      folder_name: "folder 001",
      file_name: "ab",
    },
    {
      folder_name: "folder 002",
      file_name: "ab",
    }]

  const converted_images = []

  let folders = [];

  images.forEach(img => {
    folders.includes(img.folder_name) ? null: folders.push(img.folder_name)
  })

  folders.forEach(folder => {
    let arr = images.filter(image => image.folder_name === folder)
    let file_name = [];
    arr.forEach(obj => {
      file_name.push(obj.file_name)
    })

    let object = {
      folder_name: folder,
      file_name: file_name
    }

    converted_images.push(object)
  });

  console.log(converted_images)

【讨论】:

  • 感谢您的关心和帮助
【解决方案7】:
let folderNames = [];
data.forEach(each=>{
    if(!folderNames.includes( each["folder_name"])){
    folderNames.push(each["folder_name"]);
});

let image = [];
folderNames.forEach(item=>{
    let fileNames = data.filter((i) => i["folderName"] === item && i["file_name"]);
    let tempObj = {};
    tempObj["folder_name"] = item;
    tempObj["file_name"] = fileNames;
    image.push(tempObj);
});

【讨论】:

  • 感谢您的关心和帮助
【解决方案8】:

为什么不制作文件夹地图? 所以它看起来像这样:

const images = {
    "folder 001": {
        "folder_names": [
            "anh 1",
            "anh 2",
            "anh 3"
        ]
    },
    "folder 002": {
        "folder_names": [
            "anh 1",
            "anh 2",
            "anh 3",
            "anh 4"
        ]
    }
}

间距有点奇怪,因为我实际上是这样做的,然后用制表符进行了字符串化。

无论如何,你想要这样做的方式是

let images = {};
for(let row of database){
    if(row["folder_name"] != undefined){
        if(images[row["folder_name"]] == undefined){
            images[row["folder_name"]] = {};
            images[row["folder_name"]].file_names = [];
        }
    }
    images[row["folder_name"]].file_names.concat(row["file_name"]);
}

【讨论】:

  • 感谢您的关心和帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-16
  • 2010-11-07
  • 1970-01-01
  • 2018-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多