В этом случае может быть использована ленивая оценка, если map
- единственная операция, которую вы выполняете. Spark не будет планировать исполнение до тех пор, пока на линии RDD не будет запрошено действие (в искровом выражении).
Когда вы выполните действие, произойдет println
, но не на драйвере, где вы его ожидаете, а на подчиненном устройстве, выполняющем это закрытие. Попробуйте заглянуть в журналы рабочих.
Аналогичная вещь происходит на популяции hashMap
во второй части вопроса. Тот же кусок кода будет выполнен на каждом разделе, на отдельных рабочих и будет сериализован обратно к драйверу. Учитывая, что замыкания «очищаются» от Spark, вероятно, testMap
удаляется из сериализованного закрытия, что приводит к null
. Обратите внимание, что если это было сделано только из-за невозможности выполнения map
, то hashmap должен быть пустым, а не null.
Если вы хотите перенести данные RDD в другую структуру, вам нужно сделать что в драйвере. Поэтому вам нужно заставить Spark передать все данные водителю. Это функция rdd.collect()
.
Это должно работать для вашего дела. Имейте в виду, что все данные RDD должны вписываться в память вашего драйвера:
import scala.collection.JavaConverters._
def getTestMap(dist: RDD[(String)]) = dist.collect.map(m => (m , m)).toMap.asJava
В коде есть несколько проблем:
function createGroups(totalPeople){
let i = 1
let group[i] = []; // issue #1
let array = totalPeople
totalPeople.map((user) => {
if(group[i] =< 3){ // issues #2 and #3
group[i].push(user)
}else{
array.push(group[i]); // issue #4
i++; // issue #5
}
})
};
Проблема №1:
Перед добавлением индекса вам нужно определить group
как массив.
let group = [];
group[i] = [];
Проблема №2:
Похоже, вы хотели сравнить group[i].length
и 3
Проблема № 3:
Используйте <=
вместо =<
, чтобы сравнить ваши номера. Кроме того, если вы сравните длину с <=
3, у вас будет 4 человека на группу. Поскольку первый индекс в массивах равен 0.
Проблема № 4:
Вы нажимаете array
, что является ссылкой на totalPeople
. Это то, что вы имели в виду? Потому что я сомневаюсь, что это принесет ожидаемые результаты. Вы можете инициализировать пустой массив и нажимать на него массив группы [i]. И затем верните этот новый массив. Как правило, хорошей практикой в функциональном программировании является возврат нового массива, а не изменение параметра, переданного в качестве параметра.
Проблема № 5:
Если вы увеличиваете i
, вам нужно для инициализации group[i]
в качестве массива, иначе вы не сможете нажать его, когда появится следующая итерация цикла.
Логика Differnet:
Теперь, когда вы исправили проблемы в своем коде, вот фрагмент, показывающий другой способ сделать это, используя Array.prototype.reduce :
const totalPeople = ["Joe", "Jack", "Jerry", "Jane", "Mary", "Billy", "Vicky", "Bobby"];
const groupsOfThree = totalPeople.reduce((accumulator, currentPerson, index) => {
// pushing the current person in the topest group in the accumulator
accumulator[accumulator.length-1].push(currentPerson);
// if it's the 3rd person, we're pushing the an empty group in the accumulator
if (index % 3 === 2) {
accumulator.push([]);
}
return accumulator;
}, [[]]); // the initial value of the accumulator will be an array containing an empty group
console.log(groupsOfThree);
Попробуйте инициализировать группу как массив:
let i = 1
let group = [] // Initialize as an array
group[i] = [];
let array = totalPeople
totalPeople.map((user) => {
if(group[i] =< 3){
group[i].push(user)
}else{
array.push(group[i]);
i++
}
})