У меня есть следующий код:
var nameData = [{id: "1", name: "George,Steve,Andy"},{id: "2", name: "Andy,Bradley"},{id: "3", name: "George"},{id: "4", name: "Joseph,Julia"}]
var newNames = []
for (var c=0; c<nameData.length; c++) {
//create an array of names
var names = nameData[c].name.toString().split(",")
//loop through the name array and for each name add a new entry in the newNames array
for (var n=0; n<names.length; n++) {
newNames.push(nameData[c])
newNames[newNames.length-1].name = names[n]
}
}
Мой вывод здесь следующий:
0: {id: "1", name: "Andy"}
1: {id: "1", name: "Andy"}
2: {id: "1", name: "Andy"}
3: {id: "2", name: "Bradley"}
4: {id: "2", name: "Bradley"}
5: {id: "3", name: "George"}
6: {id: "4", name: "Julia"}
7: {id: "4", name: "Julia"}
Однако мой желаемый результат был бы таким:
0: {id: "1", name: "George"}
1: {id: "1", name: "Steve"}
2: {id: "1", name: "Andy"}
3: {id: "2", name: "Andy"}
4: {id: "2", name: "Bradley"}
5: {id: "3", name: "George"}
6: {id: "4", name: "Joseph"}
7: {id: "4", name: "Julia"}
Что-то не так с присвоением атрибута name в цикле. Все записи из одного id получают фамилию в атрибуте name. Почему так и как получить желаемый результат?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы используете newNames.push(nameData[c]);, который передает ссылку на объект. Вместо этого сначала клонируйте объект, а затем нажмите.
var nameData = [{id: "1", name: "George,Steve,Andy"},{id: "2", name: "Andy,Bradley"},{id: "3", name: "George"},{id: "4", name: "Joseph,Julia"}]
var newNames = []
for (var c=0; c<nameData.length; c++) {
//create an array of names
var names = nameData[c].name.toString().split(",")
//loop through the name array and for each name add a new entry in the newNames array
for (var n=0; n<names.length; n++) {
newNames.push(Object.assign({}, nameData[c]));
newNames[newNames.length-1].name = names[n];
}
}
console.info(newNames);Вы также можете использовать reduce.
var nameData = [{id: "1", name: "George,Steve,Andy"},{id: "2", name: "Andy,Bradley"},{id: "3", name: "George"},{id: "4", name: "Joseph,Julia"}]
const output = nameData.reduce((accu, {id, name}) => {
name.split(",").forEach((name) => accu.push({id, name}));
return accu;
}, []);
console.info(output);Основываясь на вашем редактировании: я знаю, что он подталкивает один и тот же объект, но я думал, что, делая newNames[newNames.length-1].name = names[n], я корректирую последний вставленный объект в новый массив newNames и, таким образом, делаю его новым объектом (?)
@JoeBe - мне очень жаль. Вы передаете ссылку на объект - newNames.push(nameData[c]). Вместо этого вы можете клонировать объект, а затем нажать - newNames.push(Object.assign({}, nameData[c]));.
Я только что понял, что это решение по-прежнему неверно, потому что я не поддерживаю атрибуты объекта (например, в вашем примере у меня нет {id: "...", name: "..."}, а скорее {"[value of id]" : "[value of sponsor]"}. Я хочу скопировать объект и просто настроить атрибут name
если вам нравятся сокращенные решения, вы можете:
nameData.reduce((a, { id, name: names }) =>
a.concat(names.split(',').map(name => ({id, name})))
, [])
Хотя принятый поставщик ответа дает точное объяснение. Однако я думаю, что причина, по которой вы столкнулись с этой проблемой, не только реализация кода, а также дизайн кода.
Ваша реализация в low level abstraction,
вы делаете это в императиве, поэтому вам нужно обрабатывать слишком много деталей,
как loop control, mutate reference и так далее.
Я предпочитаю рефакторинг в functional style.
const newNames = nameData.flatMap(data =>
data.name.split(",").map(name => ({
id: data.id,
name
}))
);
Я думаю, что вы хотите сделать, это:
Квартира newData сплит name.
Итак, как вы можете видеть, приведенный выше пример просто квартираКарта это, и вам не нужно обрабатывать детали цикла.
Более того,
потому что map или flatMap — неизменяемая функция стиля, и мы получаем новые данные
копировать, но не изменять ссылку,
нам не нужно заботиться ни о ссылке, ни об изменении исходных данных.
Совет: flatMap — это новая функция от JS, позаботьтесь о совместимости.
Это работает. Не могли бы вы добавить какое-то объяснение, почему мой код не будет работать?