botaniQQQ
@botaniQQQ
Q

Что за аномалии с массивами в JS?

Привет.

Уже пол дня ломаю голову с такой аномалией в JS.

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

arr[arr.length] = {
	"id": 22,
  "category": 34,
	"name": "Jel",
  "movie": "Avatar"
};
arr[arr.length] = {
	"id": 34,
  "category": 12,
	"name": "Sali",
  "movie": "Ted 2"
};
arr[arr.length] = {
	"id": 33,
  "category": 34,
	"name": "Chesko",
  "movie": "Avatar"
};
arr[arr.length] = {
	"id": 22,
  "category": 34,
	"name": "Donny",
  "movie": "Avatar"
};


У него уникальные значения, это id + movie.
Нужно из него сделать вот такой:

[{
    "id": 22,
    "movie": "Avatar",
    "actors":  [{
        "category": 34,
        "name": "Jet"
    }, {
         "category": 34,
        "name": "Donny"
    }]
},
{
    "id": 34,
    "movie": "Ted 2",
    "actors":  [{
        "category": 12,
        "name": "Sali"
    }]
},
{
    "id": 33,
    "movie": "Avatar",
    "actors":  [{
        "category": 34,
        "name": "Chesko"
    }]
}]


Написал код:

var arr = [],
		movies = [];
    
arr[arr.length] = {
	"id": 22,
  "category": 34,
	"name": "Jel",
  "movie": "Avatar"
};
arr[arr.length] = {
	"id": 34,
  "category": 12,
	"name": "Sali",
  "movie": "Ted 2"
};
arr[arr.length] = {
	"id": 33,
  "category": 34,
	"name": "Chesko",
  "movie": "Avatar"
};
arr[arr.length] = {
	"id": 22,
  "category": 34,
	"name": "Donny",
  "movie": "Avatar"
};

for (var i = 0; i < arr.length; i++) {

	var id = arr[i].id + '_' + arr[i].movie;

	movies[id] = {
  	"id": arr[i].id,
    "movie": arr[i].movie
  }
  
  if (!movies[id].actors) movies[id].actors = []
  
  movies[id].actors[movies[id].actors.length] = {
  	"category": arr[i].category,
    "name": arr[i].name,
  }

}

console.log(movies);


https://jsfiddle.net/52ubh0tg/

Но он как-то аномально работает, он не увеличивает movies[id].actors[movies[id].actors.length], и все время считает что movies[id].actors пустой массив. В итоге у Avatar с id 22 только один актер, а не два.
  • Вопрос задан
  • 309 просмотров
Решения вопроса 1
HoHsi
@HoHsi
1) Не добавляйте элемент в массив через index, используйте #push
2) Проверяйте на существование переменной, вы каждый раз затираете movies[id];
3) Если вы используете конструкцию for (var i = 0; i < arr.length; i++) { }, то не вызывайте каждый раз length. Делайте так:
for (var i = 0, len = arr.length; i < len; i++) { }
, а еще лучше for (var item in arr) { }

var arr = [],
    movies = {};
    
arr.push({
  "id": 22,
  "category": 34,
  "name": "Jel",
  "movie": "Avatar"
});
arr.push({
  "id": 34,
  "category": 12,
  "name": "Sali",
  "movie": "Ted 2"
});
arr.push({
  "id": 33,
  "category": 34,
  "name": "Chesko",
  "movie": "Avatar"
});
arr.push({
  "id": 22,
  "category": 34,
  "name": "Donny",
  "movie": "Avatar"
});

movies = arr.reduce(function(res, item){
  var id = item.id + "_" + item.movie;
  
  res[ id ] = res[ id ] || {
    "id":     item.id,
    "movie":  item.movie,
  };

  res[id].actors = res[id].actors || [];

  res[id].actors.push({
    "category": item.category,
    "name":     item.name,
  });
  
  return res;
}, movies);

console.log(movies);
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Stalker_RED
@Stalker_RED
Так?
var newArr = arr.map(function(a){
  a.actors = [{
    category: a.category,
    name: a.name
  }];
  delete a.category;
  delete a.name;
  return a;
})

Демо: https://jsfiddle.net/upbmosj0/
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы