Как объединить значения переменных-членов как разделенные запятыми строки из списка объектов в переменную-член другого класса [duplicate]

Чтобы использовать только названия ресторанов, используйте код ниже.

dbReference = Database.database().reference()
dbReference?.child("Restaurants").observeSingleEvent(of: .value, with: {(snapshot) in
for rest in snapshot.children.allObjects as! [DataSnapshot] {
            print("Restaurant Name:\(rest.key)")
        }

})

И чтобы передать все данные с помощью StoryboardId, используйте ниже код.

dbReference = Database.database().reference()
dbReference?.child("Restaurants").observeSingleEvent(of: .value, with: {(snapshot) in
for rest in snapshot.children.allObjects as! [DataSnapshot] {
            print("Restaurant Data:\(rest)")

        }

})

Поместите это в свои И объявите данные переменная в destinationController, как показано ниже:

var data = [DataSnapshot]()

Вы должны выполнитьseed от didselectRowAt, как это.

performSegue(withIdentifier: "segue", sender: self)

И вы можете передать данные выбранного элемента из нижеуказанной функции.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let index = CategorytableView.indexPathForSelectedRow
let indexNumber = index?.row
print(indexNumber!)
let VC = segue.destination as! DestinationVC
VC.data = [rest] . //You can pass here entire data of selected row.

}
7
задан Tunaki 22 March 2016 в 22:15
поделиться

4 ответа

Вы можете использовать правильную лямбда для BinaryOperator в функции уменьшения.

Content c = contentList
            .stream()
            .reduce((t, u) -> new Content(
                                  t.getA() + ',' + u.getA(),
                                  t.getB() + ',' + u.getB(), 
                                  t.getC() + ',' + u.getC())
                   ).get();
4
ответ дан Mrinal 27 August 2018 в 07:08
поделиться
static Content merge(List<Content> list) {
    return new Content(
            list.stream().map(Content::getA).collect(Collectors.joining(", ")),
            list.stream().map(Content::getB).collect(Collectors.joining(", ")),
            list.stream().map(Content::getC).collect(Collectors.joining(", ")));
}

EDIT: расширяя встроенный сборщик Federico, вот конкретный класс, посвященный объединению объектов Content:

class Merge {

    public static Collector<Content, ?, Content> collector() {
        return Collector.of(Merge::new, Merge::accept, Merge::combiner, Merge::finisher);
    }

    private StringJoiner a = new StringJoiner(", ");
    private StringJoiner b = new StringJoiner(", ");
    private StringJoiner c = new StringJoiner(", ");

    private void accept(Content content) {
        a.add(content.getA());
        b.add(content.getB());
        c.add(content.getC());
    }

    private Merge combiner(Merge second) {
        a.merge(second.a);
        b.merge(second.b);
        c.merge(second.c);
        return this;
    }

    private Content finisher() {
        return new Content(a.toString(), b.toString(), c.toString());
    }
}

Используется как:

Content merged = contentList.stream().collect(Merge.collector());
4
ответ дан AJNeufeld 27 August 2018 в 07:08
поделиться

Если вы не хотите повторять три раза по списку или не хотите создавать слишком много промежуточных объектов Content, вам нужно будет собрать поток со своей собственной реализацией:

public static Content collectToContent(Stream<Content> stream) {
    return stream.collect(
        Collector.of(
            () -> new StringBuilder[] {
                    new StringBuilder(),
                    new StringBuilder(),
                    new StringBuilder() },
            (StringBuilder[] arr, Content elem) -> {
                arr[0].append(arr[0].length() == 0 ? 
                        elem.getA() : 
                        ", " + elem.getA());
                arr[1].append(arr[1].length() == 0 ? 
                        elem.getB() : 
                        ", " + elem.getB());
                arr[2].append(arr[2].length() == 0 ? 
                        elem.getC() : 
                        ", " + elem.getC());
            },
            (arr1, arr2) -> {
                arr1[0].append(arr1[0].length() == 0 ?
                        arr2[0].toString() :
                        arr2[0].length() == 0 ?
                                "" :
                                ", " + arr2[0].toString());
                arr1[1].append(arr1[1].length() == 0 ?
                        arr2[1].toString() :
                        arr2[1].length() == 0 ?
                                "" :
                                ", " + arr2[1].toString());
                arr1[2].append(arr1[2].length() == 0 ?
                        arr2[2].toString() :
                        arr2[2].length() == 0 ?
                                "" :
                                ", " + arr2[2].toString());
                return arr1;
            },
            arr -> new Content(
                    arr[0].toString(), 
                    arr[1].toString(), 
                    arr[2].toString())));
}

Этот коллекционер сначала создает массив из трех пустых StringBuilder объектов. Затем определяет накопитель, который добавляет свойство каждого элемента Content к соответствующему StringBuilder. Затем он определяет функцию слияния, которая используется только тогда, когда поток обрабатывается параллельно, что объединяет два ранее накопленных частичных результата. Наконец, он также определяет функцию финишера, которая преобразует объекты 3 StringBuilder в новый экземпляр Content, причем каждое свойство соответствует накопленным строкам предыдущих шагов.

Пожалуйста, проверьте Stream.collect() и Collector.of() javadocs для дополнительной справки.

3
ответ дан Federico Peralta Schaffner 27 August 2018 в 07:08
поделиться

Наиболее общий способ решения таких задач состоял в том, чтобы объединить результат нескольких коллекторов в один.

Используя библиотеку jOOL , вы могли бы иметь следующее :

Content content = 
    Seq.seq(contentList)
       .collect(
         Collectors.mapping(Content::getA, Collectors.joining(", ")),
         Collectors.mapping(Content::getB, Collectors.joining(", ")),
         Collectors.mapping(Content::getC, Collectors.joining(", "))
       ).map(Content::new);

Это создает Seq из списка ввода и объединяет 3 заданных коллектора для создания Tuple3, который просто является держателем для 3 значений. Эти 3 значения затем отображаются в Content с использованием конструктора new Content(a, b, c). Сам сборщик просто отображает каждый Content в его значение a, b или c и объединяет результаты вместе, разделенные с помощью ", ".


Без сторонних мы можем создать наш собственный сборщик объединителей (это основано на сборнике StreamEx pairing , что делает то же самое для 2 коллекционеров). Он принимает 3 коллектора в качестве аргументов и выполняет операцию финишера по результату 3 собранных значений.

public interface TriFunction<T, U, V, R> {
    R apply(T t, U u, V v);
}

public static <T, A1, A2, A3, R1, R2, R3, R> Collector<T, ?, R> combining(Collector<? super T, A1, R1> c1, Collector<? super T, A2, R2> c2, Collector<? super T, A3, R3> c3, TriFunction<? super R1, ? super R2, ? super R3, ? extends R> finisher) {

    final class Box<A, B, C> {
        A a; B b; C c;
        Box(A a, B b, C c) {
            this.a = a;
            this.b = b;
            this.c = c;
        }
    }

    EnumSet<Characteristics> c = EnumSet.noneOf(Characteristics.class);
    c.addAll(c1.characteristics());
    c.retainAll(c2.characteristics());
    c.retainAll(c3.characteristics());
    c.remove(Characteristics.IDENTITY_FINISH);

    return Collector.of(
            () -> new Box<>(c1.supplier().get(), c2.supplier().get(), c3.supplier().get()),
            (acc, v) -> {
                c1.accumulator().accept(acc.a, v);
                c2.accumulator().accept(acc.b, v);
                c3.accumulator().accept(acc.c, v);
            },
            (acc1, acc2) -> {
                acc1.a = c1.combiner().apply(acc1.a, acc2.a);
                acc1.b = c2.combiner().apply(acc1.b, acc2.b);
                acc1.c = c3.combiner().apply(acc1.c, acc2.c);
                return acc1;
            },
            acc -> finisher.apply(c1.finisher().apply(acc.a), c2.finisher().apply(acc.b), c3.finisher().apply(acc.c)),
            c.toArray(new Characteristics[c.size()])
           );
}

и, наконец, использовать его с

Content content = contentList.stream().collect(combining(
    Collectors.mapping(Content::getA, Collectors.joining(", ")),
    Collectors.mapping(Content::getB, Collectors.joining(", ")),
    Collectors.mapping(Content::getC, Collectors.joining(", ")), 
    Content::new
));
4
ответ дан Tunaki 27 August 2018 в 07:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: