Из функции со стрелкой переместить объект в массив

#javascript #arrays #loops #object #arrow-functions

#javascript #массивы #петли #объект #стрелка-функции #циклы

Вопрос:

Функция async / await search возвращает объект, подобный:

 [
  {
    "title":"page title",
    "url":"/page/url/index.html",
    "content":"blah blah blah"
  },
  ...
]
  

Мне нужно поместить каждый объект из val в массив, но когда я нажимаю с помощью:

 results = [];
search(input).then(val=> results.push(val));
  

Я получаю вложенный массив, подобный (я хочу, чтобы записи объекта были верхнего уровня в массиве):

 [
  [
    {title:"...", url:"...", content:"..."},
    {title:"...", url:"...", content:"..."},
  ]
]
  

Поэтому я попробовал for с помощью стрелки поместить каждую запись в объекте в массив, но, похоже, это не сработало.

 results = [];
search(input).then(val=> for(i in val) {results.push(val[i])});
  

Комментарии:

1. Попробуйте это: поиск (ввод). затем (val=> results.push(…val));

2. Ты не можешь просто использовать results = val ? хотя я на самом деле не вижу смысла делать это, поскольку вы сможете получить доступ к заполненной версии results только после того, как ваше обещание будет выполнено, например, в .then() обратном вызове, так что вы могли бы также просто использовать val

3. Попробуйте search(input).then(val=> [].concat(results, val));

Ответ №1:

Вместо .push() используйте .concat()

 results = [];
search(input).then(val=> { results = results.concat(val) });
  

Ответ №2:

Используйте синтаксис распространения ...

Также не For loop требуется.

 search(input).then(val=> results = [...results,...val]);
  

или как предложил @Patrick_Hund

 search(input).then(val=> results.push(...val));
  

здесь проблема в том, что вы помещаете array в массив.

Вам нужно переместить элементы массива.

Расширение синтаксиса должно устранить проблему.

Надеюсь, теперь у вас есть четкое понимание.

Комментарии:

1. push принимает произвольное количество аргументов, поэтому вы можете просто использовать оператор spread в val для получения результатов: search(input).then(val=> results.push(...val));

2. цикл for здесь не нужен

3. @PatrickHund — отправьте свой ответ, и я приму. Спасибо.

Ответ №3:

Если у вас есть массив и вы вызываете функцию, которая вернет Promise<array> вам не нужно выполнять какие-либо итерации с результатом. Объединить массивы:

 async function getNewData() {
  return Promise.resolve([{
    d: 1
  }, {
    e: 3
  }]);
}

let results = [{
  a: 3
}, {
  b: 4
}];

getNewData().then(newdata => {
  results = results.concat(newdata); 
  // same as results = [...results, ...newdata];

  console.log(results);
});  

С другой стороны, вы также можете нажать, используя оператор распространения

 async function getNewData() {
  return Promise.resolve([{
    d: 1
  }, {
    e: 3
  }]);
}

const results = [{
  a: 3
}, {
  b: 4
}];

getNewData().then(newdata => {
  results.push(...newdata); 
  // same as results.push(newdata[0], newdata[1], etc)

  console.log(results);
});  

Такой подход может сбивать с толку, поскольку люди склонны игнорировать переменную природу Array.prototype.push, но он позволяет избежать повторного объявления results , поэтому вы можете объявить целевой массив как const .

Ответ №4:

Если вы хотите использовать цикл for, вам придется выполнить

 for(var i=0; i < val.length; i  ) {
    results.push(val[i])
}
  

Есть более сжатые способы сделать это (см. Комментарий Патрика Ханда), но именно так вы делаете это с помощью цикла for.