Упорядывачение данных

303
24 июля 2017, 17:05

Есть исходный массив:

[ 'dev/img/sprites/coctail/coc-1.png',         
  'dev/img/sprites/coctail/coc-2.png',         
  'dev/img/sprites/coctail/coc-3.png',         
  'dev/img/sprites/coctail/coc-4.png',         
  'dev/img/sprites/coctail/coc-5.png',         
  'dev/img/sprites/social/advan-1.png',        
  'dev/img/sprites/social/advan-2.png',        
  'dev/img/sprites/social/advan-3.png',        
  'dev/img/sprites/social/advan-4.png',        
  'dev/img/sprites/testSprite1/s19908f1255e3d10,
  'dev/img/sprites/testSprite1/shutterstock_106,
  'dev/img/sprites/testSprite1/tel.jpg',       
  'dev/img/sprites/testSprite1/unnamed.png' ] 

Необходимо на его основе сделать массив объектов, который выглядит так:

[ { data:                                                                
     [ 'dev/img/sprites/coctail/coc-1.png',                              
       'dev/img/sprites/coctail/coc-2.png',                              
       'dev/img/sprites/coctail/coc-3.png',                              
       'dev/img/sprites/coctail/coc-4.png',                              
       'dev/img/sprites/coctail/coc-5.png' ],                            
    fileName: 'coctail',                                                 
    destPath: 'app/img/' },                                              
  { data:                                                                
     [ 'dev/img/sprites/social/advan-1.png',                             
       'dev/img/sprites/social/advan-2.png',                             
       'dev/img/sprites/social/advan-3.png',                             
       'dev/img/sprites/social/advan-4.png' ],                           
    fileName: 'social',                                                  
    destPath: 'app/img/' },                                              
  { data:                                                                
     [ 'dev/img/sprites/testSprite1/s19908f1255e3d106eca5d.jpg',         
       'dev/img/sprites/testSprite1/shutterstock_106748483-247x180.jpg', 
       'dev/img/sprites/testSprite1/tel.jpg',                            
       'dev/img/sprites/testSprite1/unnamed.png' ],                      
    fileName: 'testSprite1',                                             
    destPath: 'app/img/' } ]    

В принципе задача решена, но тот код, который я написал мне самому не очень нравиться. Получилось много циклов и как-то громоздко.
Может кто посмотрит и укажет, где можно было сделать более компактно?

var fileNames = new Set(); 
var files = []; 
var destination = new Set(); 
//console.log(matches) 
matches.forEach((item, i, arr) => { 
  if (item.includes(config.spritesFolder)) { 
    var pos = item.indexOf(config.spritesFolder); 
    var start = item.indexOf('/', pos) + 1; 
    var end = item.indexOf('/', start); 
    fileNames.add(item.slice(start, end)); 
    destination.add(item.slice(0, pos)); 
  } 
}); 
var i = 0; 
fileNames.forEach((item, it, arr) => { 
  files[i] = {}; 
  files[i].data = []; 
  files[i].fileName = item; 
  for (var j = 0; j < matches.length; j++) { 
    if (matches[j].indexOf(item) != -1) { 
      files[i].data.push(matches[j]); 
    } 
  } 
  i++; 
}); 
for (var i = 0; i < files.length; i++) { 
  files[i].destPath = ''; 
  destination.forEach((item, it, arr) => { 
    if (files[i].data[0].indexOf(item) != -1) { 
      files[i].destPath = item.replace(config.path.src.dir, config.path.build.dir); 
    } 
  }); 
} 
console.dir(files)

Answer 1
    var arr = ['dev/img/sprites/coctail/coc-1.png',
    'dev/img/sprites/coctail/coc-2.png',
    'dev/img/sprites/coctail/coc-3.png',
    'dev/img/sprites/coctail/coc-4.png',
    'dev/img/sprites/coctail/coc-5.png',
    'dev/img/sprites/social/advan-1.png',
    'dev/img/sprites/social/advan-2.png',
    'dev/img/sprites/social/advan-3.png',
    'dev/img/sprites/social/advan-4.png',
    'dev/img/sprites/testSprite1/s19908f1255e3d10',
    'dev/img/sprites/testSprite1/shutterstock_106',
    'dev/img/sprites/testSprite1/tel.jpg',
    'dev/img/sprites/testSprite1/unnamed.png',
    'dev/img/sprites/testSprite2/unnamed.png',
    'dev/img/sprites/testSprite3/unnamed.png'],
i = newArrLength = 0,
newArr = [],
tempArr2 = tempArr = [],
createData = function (file, path) {
    this.data = tempArr;
    this.filename = file;
    this.path = path;
};
while (i < arr.length) {
    var splited1 = arr[i].split('/');
    splited2 = arr[i + 1] ? arr[i + 1].split('/') : false;
    if (splited1[3] === splited2[3]) {
        tempArr[tempArr.length] = arr[i];
    } else {
        tempArr[tempArr.length] = arr[i];
        tempArr2 = new createData(splited1[3], splited1[0] + '/' + splited1[1]);
        newArr[newArr.length] = tempArr2;
        tempArr = tempArr2 = [];
    };
    ++i;
}
console.log(newArr[0]);
Answer 2

Немного поразмышляв переписал код следующим образом:

var matches = ['dev/img/sprites/coctail/coc-1.png', 
  'dev/img/sprites/coctail/coc-2.png', 
  'dev/img/sprites/coctail/coc-3.png', 
  'dev/img/sprites/coctail/coc-4.png', 
  'dev/img/sprites/coctail/coc-5.png', 
  'dev/img/sprites/social/advan-1.png', 
  'dev/img/sprites/social/advan-2.png', 
  'dev/img/sprites/social/advan-3.png', 
  'dev/img/sprites/social/advan-4.png', 
  'dev/img/sprites/testSprite1/s19908f1255e3d106eca5d.jpg', 
  'dev/img/sprites/testSprite1/shutterstock_106748483-247x180.jpg', 
  'dev/img/sprites/testSprite1/tel.jpg', 
  'dev/img/sprites/testSprite1/unnamed.png' 
] 
 
var files = []; 
 
function createItem(arr, i, prop, item) { 
  arr[i] = {}; 
  arr[i][prop] = []; 
  arr[i][prop].push(item) 
  if (!arr[i].fileName && !arr[i].destPath) { 
    var pos = item.indexOf('sprites'); 
    var start = item.indexOf('/', pos) + 1; 
    var end = item.indexOf('/', start); 
    arr[i].fileName = item.slice(start, end); 
    arr[i].destPath = item.slice(0, pos).replace('dev', 'app'); 
  } 
} 
var j = 0; 
matches.forEach((item, i, arr) => { 
  var pos = item.lastIndexOf('/'); 
  if (files.length == 0) { 
    createItem(files, j, 'data', item); 
  } else if (files[j].data[files[j].data.length - 1].includes(item.slice(0, pos))) { 
    files[j].data.push(item); 
  } else { 
    j++; 
    createItem(files, j, 'data', item); 
  } 
}); 
console.log(files);

Я решил создавать объекты в массве files прямо в цикле по matches и использовать дополнительную функцию для создания необходимых свойств этих объектов.

READ ALSO
Наклон устройства

Наклон устройства

Ребят, столкнулся с такой проблемойДелаю приложение на cordova

332
Месяц в родительном падеже momentjs

Месяц в родительном падеже momentjs

ПриветКак вывести дату в родительном падеже в momentjs? Например, не сентябрь, а сентября

359
Не работают JS-скрипты в Roundcube

Не работают JS-скрипты в Roundcube

СутокДля одного из проектов понадобилось развернуть собственный почтовый сервер и webmail'ом был выбран Roundcube

241