Собираем массив объектов 5/5

let getZippedArrays = (key,value)=>key.reduce((acum,elem,index)=>{
 acum[elem] = value[index];
return acum
},{})

У меня вот так получилось:

let getData = function (keysData, meaningsData) {
  let dataBase = [];
  for (let i = 0; i < meaningsData.length; i++) {
    let result = {};
    for (let j = 0; j < meaningsData[i].length; j++) {
      if (meaningsData[i][j] === undefined || keysData[j] === undefined) break;
      result[keysData[j]] = meaningsData[i][j];
    }
    dataBase.push(result);
  }
  return dataBase;
};
let getData=function(arrayKays,arrayData){
    
  let newArray=[];
  let shortestLength=arrayKays.length;
  for(i=0;i<arrayData.length;i++){
    newArray[i]={};
    
      if(shortestLength>arrayData[i].length){
        shortestLength=arrayData[i].length}
        
          for(j=0;j<shortestLength;j++){
              newArray[i][arrayKays[j]]=arrayData[i][j];
              }
        }
      return newArray;
  }

let getData = function (arrKeys, arrData) {
let result = [];
for (let i = 0; i < arrData.length; i++) {
result[i]={};
for (let j = 0; j < arrData[i].length && j < arrKeys.length; j++) {
result[i][arrKeys[j]]=arrData[i][j];
}
}
return result
}

const getData =(arr1,arr2)=>arr2.map((elem) => elem.reduce( (acum, el, ind) => ind < arr1.length ? { ...acum, [arr1[ind]]: el } : { ...acum }, {} ) );

1 лайк

Проще сразу на Ассемблере писать. Читаемость не станет хуже :+1:

2 лайка
let arr = [];
let obj = {};

let getData = function (key, data) {
  for(let i = 0; i < data.length; i++) {
    for(let j = 0; j < data[i].length; j++) {
      if(data[i].length <= key.length) {
        obj[key[j]] = data[i][j];
        } else {
            for(let k = 0; k < key.length; k++) {
            obj[key[k]] = data[i][k];
            }
          }
    } 
    arr.push(obj);
    obj= {};
  }

return arr;
}

let arrKey = [];
let arrData = [];

getData(arrKey, arrData);

Целый вечер + вытекший на стол мозг, итого 23.53 проверку прошел, окончательно осознаю что вышло только завтра:

array = [];

let getData = function (keysArray, dataArray) {

for (let i=0; i<dataArray.length; i++) {
     let object = {};      
 
       for (let j=0; j<keysArray[i].length; j++) {
          if (keysArray[j] && dataArray[i][j]) {
              object[keysArray[j]] = dataArray[i][j]           
          } 
       }
      
array.push(object) } 

return array
}

Подскажите почему код не проходит вторую проверку, ведь как по мне все должно работать?

array = [];

let getData = function (keysArray, dataArray) {

for (let i=0; i<keysArray.length; i++) {
     let object = {};      
 
       for (let j=0; j<keysArray.length; j++) {
          if (keysArray[j] && dataArray[i][j]) {
              object[keysArray[j]] = dataArray[i][j]           
          } 
       }
      
array.push(object) } 

return array
}

let getData = function (arrKeys, arrValues) {
        let arr = [];
        for (let j = 0; j < arrKeys.length && j < arrValues.length; j++) {
            let obj = {};
            for (let i = 0; i < arrValues[j].length && i < arrKeys.length; i++) {
                obj[arrKeys[i]] = arrValues[j][i];
            }
            arr.push(obj);
        }  
        return arr;
    };

Прошёл проверку с таким кодом.

Сводка
let getData = function (arrKey, arrArr) {
  let arrObj = []
  for (let i=0;i<arrArr.length;i++) {
  let obj = {};
  for (let j=0;j<arrArr.length;j++) {
    if (!arrKey[j] || !arrArr[i][j]) {break};
    obj[arrKey[j]] = arrArr[i][j];
      } 
    arrObj.push(obj);
  }
return arrObj;
}

Всем, Привет!
Подскажите, в чем может быть ошибка.
Решение не проходит второй тест.

let getZippedArrays = function (arrKeys, arrProp) {
let result = {};
for (let i = 0; i < arrKeys.length; i++) {
if (!arrProp) continue;
else result[arrKeys[i]]= arrProp[i];
}
return result;
}

let getData = function (arrK, arrP) {
let result = [];
for (let i = 0; i<arrK.length; i++) {
if (!!!arrP[i]) continue;
else result[i] = getZippedArrays(arrK,arrP[i]);
}
return result;

}

Если ответить совсем коротко, то ошибка кроется в строчке "if (!arrProp) continue; функции getZippedArrays. Там должно быть вот так “if (!arrProp[i])”

1 лайк

Если чуть дольше, то лучше написать хотя бы как-то так

const getZippedArrays = (arrKeys, arrProp) => {
    const result = {};
    for (let i = 0; i < arrKeys.length; i++) {
        if (arrProp[i]) {
            result[arrKeys[i]] = arrProp[i];
        }
    }
    return result;
};

const getData = (arrK, arrP) => {
    const result = [];
    for (let i = 0; i < arrK.length; i++) {
        if (arrP[i]) {
            result[i] = getZippedArrays(arrK, arrP[i]);
        }
    }
    return result;
};

Что исправлено и почему.

  1. Лучше использовать const везде там, где это возможно
  2. Лучше использовать стрелочные функции, всё-таки современнее
  3. Три восклицательных знака в условии не имеют значения, нужен всего 1
  4. continue тоже лучше не использовать, в данном случае без него лучше и чище

Далее интереснее. В данном коде мы мысли как-то следующим образом: “У нас есть массив ключей и массив массивов со значениями. Давайте создадим цикл, который будет проходить по массиву со значениями. И для каждого из значений мы дополнительно создадим цикл, который будет проходиться по ключам, смотреть на наличие значения для этого ключа и собирать всё в объект”. Это императивный стиль написания кода.

Интереснее было бы написать более декларативно. И мыслить в данном случае вот как: “У нас есть массив с массивами значений. Давайте опишем не то, что мы сделаем с этими данными, а то, что с ними должно произойти, т.е. опишем каким образом мы хотим, чтобы выглядел результат.”

Что это значит? Это значит, что мыслим дальше… У нас есть массив массивов. На выходе мы получим массив объектов. Размер этого массива очевидно будет равен размеру исходного массива значений. Давайте тогда возьмём исходный массив и вернём его же, но преобразованный. Преобразовать массив нам поможет функция map.
Так же мы помним, что нам нужно преобразовать массив в объект при помощи массива ключей. Итого каждый массив значений превращается в объект, ключи которого мы берём из массива ключей, а значения из массива значения. Сделать это можно вот так.

const getData = (keys, keysDataArray) =>
    keysDataArray.map((dataArray) =>
        keys.reduce((acc, current, i) => {
            const value = dataArray[i];
            if (value) {
                acc[current] = value;
            }
            return acc;
        }, {}),
    );

И то вряд ли это можно назвать эталонным решением

1 лайк

Да, в условной конструкции перемудрила, но три восклицательных знака не просто так, это я вычитала такую проверку на undefined.


Map, reduce умышленно не стала использовать. Пока что, владею этими методами не очень уверенно, начала бы блуждать в колбэк функциях и при отладке в браузере не очень прозрачно, что откуда и куда, поэтому пошла путем разбивки на две функции, мне показалось, что само условие задачи на это намекает.
Спасибо большое за ответ и замечания. Все учту.

Статья мягко говоря сомнительного качества, да и вообще, если в статьях люди пишут о том, что они “любят экспериментировать”, то это чаще всего маркер дурной статьи. Почему? Потому что с языком не нужно экспериментировать. Там нечего первооткрывать и магии в нём тоже нет. У него есть спецификация и в ней можно найти все особенности его поведения (всё, что нужно в 99% случаев).
Экспериментировать можно с закрытыми реализациями этого языка в разных браузерах, но это тема отдельная. Теперь по порядку.

Нет никаких операторов двойного (!!) или тройного (!!!) восклицательного знака, а есть лишь один - это восклицательный знак, логическое НЕ.

Далее, когда мы используем оператор if, мы передаём в него что-то, что в конечном счёте должно быть преобразовано к булевому значению. Про преобразования типов есть хороший материал вот здесь. В частности хочу обратить внимание на строгое и нестрогое неравенство.

Т.е. это я к тому, что внутри if значение будет преобразовано к типу Boolean само.
Что происходит, когда мы пишем что-то в духе if(!param)? Мы как бы говорим “Выполни условие, если param отсутствует или равно false”, соответственно, если, например переменная окажется undefined, то условие окажется верным. В нашем случае нужно “Что-то сделать” если свойство есть и ничего не делать в обратном случае.

Откуда взялись два восклицательных знака и для чего они нужны? Если вкратце, то их использование в операторе if() бессмысленно и вредно с точки зрения читаемости кода.
Нет такого примера, когда бы данные два выражения работали бы по разному при одном и том же значении переменной внутри if:

1. if(param) {}
2. if(!!param) {}

Однако двойной восклицательный знак может быть полезен, когда мы хотим явно преобразовать значение к типу Boolean. Например вот такой код:

const param = {};
const defaultCondition = true;
const someCondition = !!param || defaultCondition;

В данном случае значение переменной someCondition окажется равной true, однако если бы мы написали просто

const someCondition = param || defaultCondition;

То значение окажется равным пустому объекту {}, однако такой код тоже является не очень хорошим с точки зрения восприятия и подходу к решению задачи в целом…

Итого, попытаюсь подытожить мысли. Использовать три восклицательных знака точно никогда не нужно, использовать два восклицательных знака иногда бывает нужно, но чаще всего не стоит так делать.
По поводу undefined… Это отдельная конечно тема, но в подавляющем большинстве случаев нам не очень интересно что внутри переменной в операторе if, нам нужно лишь определиться, что делать если значением там есть или там что-то кроме значения, поэтому никаких дополнительных преобразований и проверок делать не стоит.

Если же у нас есть исключительный кейс, когда нам точно нужно знать undefined это или null, мы вынуждены прибегать к строгой проверке if(param === undefined) или if(param === null).

И есть ещё один нюанс. Если значение, которое предполагается присвоить по ключу будет false, то оно будет утрачено… В примере выше такая ситуация невозможна, но в целом, если бы мы хотели предусмотреть и этот случай, то пришлось бы использовать проверку в духе if(param != undefined) :))

P.S. В общем то и нет разницы есть ли значение по индексу массива или оно равно undefined, в любом случае оно нам не подходит

Учу js только по программе (за исключением базовых стрелочных функций)
Исходя из материала, который прошел у меня получилось следующее решение

let getData = (key, mass) => {
let final = [];
for (let i = 0; i < mass.length; i ++) {
let obj = {};
let length = mass[i].length;
if (mass[i].length > key.length ) {
length = key.length;
}
for (let x = 0; x < length; x ++) {
obj[key[x]] = mass[i][x];
}
final.push(obj);
}
return final;
};

Буду рад конструктивной критике и ревьюшке

1 лайк
let getData = function(keys, data) {
  let arr = [];
  for(let i = 0; i < data.length; i++) {
   let obj = {};
    for(let j = 0; j < keys.length; j++) {
    if(obj[keys[j]] != undefined || data[i][j] != undefined) {
    obj[keys[j]] = data[i][j];
    }
}
 arr.push(obj);
}
return arr; 
};

Точно такой же вопрос: не проходит вторую проверку, хотя результат идентичный с таким кодом:
function getData(keys, s){
var a = []
for(let i=0;i<s.length;i++){
let b = {}
for(let j=0;j<keys.length;j++){
b[keys[j]] = s[i][j]
}
a.push(b)
}
return a
}

Screenshot (109)

1 лайк

Спасибо! У меня практически такой же код, только я не добавлял проверку на длину между циклами for. В итоге, мой код изначально не проходил второй тест (хотя результат был одинаковым). Странно, что интерпретатор выдаёт одинаковые результаты, но решение не валидирует.