перебор объектов javascript без сортировки на основе ключей

#javascript #object

#javascript #объект

Вопрос:

это описание проблемы: Учитывая массив целых чисел, вычислите доли его элементов, которые являются положительными, отрицательными и равными нулям. Выведите десятичное значение каждой дроби в новой строке. например, учитывая, что вывод массива arr=[1,1,0,-1,-1] должен быть:

 0.400000
0.400000
0.200000
  

Я знаю, что для этого есть более простое решение, и я прошу прощения за мой глупый простой вопрос, но я хочу, чтобы мой код работал, мой код сортирует выходные данные на основе ключа и удаляет дубликаты. для этого arr мой вывод кода:

 0.200000
0.400000
  

заранее большое спасибо за любую помощь.

 function plusMinus(arr) {
    var freq = {};
    for (var i = 0; i < arr.length; i  ){
        if (freq[arr[i]]) {
            freq[arr[i]]  ;
        } else {
            freq[arr[i]] = 1;
        }
    } for(var key in freq){

        console.log((freq[key]/arr.length).toFixed(6));
    }
    }
  

Ответ №1:

Вы могли бы взять объект с предопределенными свойствами, это предотвратит каждый цикл проверки существования и взять массив ключей для получения результата в желаемом порядке.

 function plusMinus(arr) {
    var freq = { 1: 0, '-1': 0, 0: 0 },
        i, key;

    for (i = 0; i < arr.length; i  ) {
        freq[arr[i]]  ;
    }

    for (key of [1, -1, 0]) {
        console.log((freq[key] / arr.length).toFixed(6));
    }
}

plusMinus([1, 1, 0, -1, -1]);  

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

1. Число может быть любым целым числом в соответствии с вопросом. Возможно, вам придется выполнить: freq[Math.sign(arr[i])]

2. @adiga, верно, для любого целого числа знака должно быть достаточно.

3. @NinaScholz порядок сейчас правильный, но дубликаты по-прежнему удаляются, вывод должен быть 0.4, 0.4, 0.2, но он выдает 0.4, 0.2 , почему это?

4. я не понимаю последний вывод. что вы получаете?

Ответ №2:

Давайте проверим порядок следования ключей в карте, определив его первым.

 function plusMinus(arr) {
  var freq = {
    posetive: 0,
    negative: 0,
    zero: 0
  };
  for (var i = 0; i < arr.length; i  ){
    if( arr[i] < 0) {
      freq.negative  ;
    } else if(arr[i] > 0) {
      freq.posetive  ;
    } else {
      freq.zero  ;
    }
  } 
  for(var key in freq){
    console.log((freq[key]/arr.length).toFixed(6));
  }
}
plusMinus([1,1,0,-1,-1]);  

Ответ №3:

Вы можете использовать reduce.

Идея заключается в

  • Сначала выполните цикл по исходному массиву и проверьте значение.
  • Если значение равно нулю, мы увеличиваем количество zero ключей.
  • Если значение равно, positive мы увеличиваем количество pos ключей.
  • Если значение равно, negative мы увеличиваем количество neg ключей.
  • Наконец, мы делим каждое количество на длину массива.

 let arr = [1,1,0,-1,-1]

let op = arr.reduce((op,inp)=>{
  if(inp === 0){
    op.zero.count  
  } else if (inp > 0){
    op.pos.count  ;
  } else {
    op.neg.count  ;
  }
  return op
},{zero:{count:0},pos:{count:0},neg:{count:0}})


let final = Object.entries(op).map(([key,value])=>({
  [key] : value.count / arr.length
}))

console.log(final)  

Ответ №4:

Используйте reduce , map и filter :

 const arr = [1, 1, 0, -1, -1];

const counts = arr.reduce((acc, curr) => {
  if (!curr) acc[0]  ;
  else if (curr > 0) acc[1]  ;
  else acc[2]  ;
  return acc
}, [0, 0, 0]);

const result = counts.map(e => e / arr.length).filter((e, i, a) => a.indexOf(e) == i);

console.log(result);  

Ответ №5:

Вы можете попробовать использовать Array.reduce , и результирующий массив будет иметь долю от положительного числа по ‘0’-му индексу, отрицательного по ‘1’-му и нулевого по ‘2’-му индексу.

Теперь, если вы хотите контролировать количество элементов после запятой, используйте Array.map в конце, чтобы преобразовать его.

 const array = [1,1,0,-1,-1];
function plusMinus(arr){
  const output = arr.reduce((acc, ele) => {
  if(ele > 0){
    acc[0] = ((acc[0] || 0 )   1 / arr.length);
  }
  if(ele < 0){
    acc[1] = ((acc[1] || 0 )   1 / arr.length);
  }
  if(ele === 0) {
    acc[2] = ((acc[2] || 0 )   1 / arr.length);
  }
  return acc;
  }, []).map(ele => ele.toFixed(6));
 console.log(...output);
}
plusMinus(array);  

Ответ №6:

Math.sign здесь твой друг. Math.sign

Кроме того, Lodash действительно помог бы сделать этот фрагмент более чистым, я настоятельно рекомендую _.countBy . Lodash .countBy

Вот код.

 const plusMinus = (numbers) => {
  // Count by Sign (-1, 0 1)
  const countSign = _.countBy(numbers, Math.sign);
  // _.countBy return object, of counted { '1': 2, '0': 1, '-1': 2 } 
  
  // Print them in orders
  const printOrder = [1, -1, 0];
  printOrder.forEach(sign => {
    console.log((countSign[sign] / numbers.length).toFixed(6));
  });
}

const testArr = [1,1,0,-1,-1];
plusMinus(testArr);  
 <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>  

Ответ №7:

Вот еще одно однострочное решение, использующее функции Array.reduce() и Array.forEach() :

 const plusMinus = arr => arr
  .reduce((res, curr) =>   res[!curr ? 2 : curr < 0 ? 1 : 0] amp;amp; res, [0, 0, 0])
  .forEach(i => console.log((i / arr.length).toFixed(6)));

plusMinus([1, 1, 0, -1, -1]);